@@ -1,231 +1,40 @@
1−import React, { useCallback, useMemo, useState } from 'react';
2−import { Grid, Text, P, LinkButton } from 'indigo-react';
3−import * as azimuth from 'azimuth-js';
1+import React, { useCallback, useState } from 'react';
2+import { Grid } from 'indigo-react';
3+import { azimuth } from 'azimuth-js';
44
5−import { useNetwork } from 'store/network';
6−import { usePointCursor } from 'store/pointCursor';
7−
8−import * as need from 'lib/need';
9−import useEthereumTransaction from 'lib/useEthereumTransaction';
10−import { GAS_LIMITS } from 'lib/constants';
11−import { useLocalRouter } from 'lib/LocalRouter';
12−
13−import ViewHeader from 'components/ViewHeader';
14−import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
155import View from 'components/View';
16−import BridgeForm from 'form/BridgeForm';
17−import convertToInt from 'lib/convertToInt';
18−
19−function useCastDocumentVote() {
20− const { contracts } = useNetwork();
21− const { pointCursor } = usePointCursor();
22−
23− const _contracts = need.contracts(contracts);
24− const _point = need.point(pointCursor);
25−
26− return useEthereumTransaction(
27− useCallback(
28− (hash, accept) => {
29− return azimuth.ecliptic.castDocumentVote(
30− _contracts,
31− _point,
32− hash,
33− accept
34− );
35− },
36− [_contracts, _point]
37− ),
38− useCallback(() => null, []), //TODO update polls[hash].hasVoted ?
39− GAS_LIMITS.DEFAULT //TODO update once we have a decent sample size
40− );
41−}
42−
43−function renderDocumentHash(doc) {
44− return doc.slice(0, 34) + '\n ' + doc.slice(34);
45−}
46−
47−export default function Senate() {
48− const { pop } = useLocalRouter();
49− const { contracts } = useNetwork();
50− const { pointCursor } = usePointCursor();
51−
52− const _contracts = need.contracts(contracts);
53− const _point = convertToInt(need.point(pointCursor), 10);
54−
55− const { construct, bind } = useCastDocumentVote();
56−
57− // const [documentHash, setDocumentHash] = useState('0x...');
58− const [majorities, setMajorities] = useState([]);
59− const [proposals, setProposals] = useState([]);
60− const [polls, setPolls] = useState({});
61− const [loading, setLoading] = useState(true);
62− const [votingOn, setVotingOn] = useState({});
63−
64− //TODO update every second?
65− const now = Math.round(new Date().getTime() / 1000);
66−
67− useMemo(async () => {
68− let proposals = await azimuth.polls.getDocumentProposals(_contracts);
69− let majorities = await azimuth.polls.getDocumentMajorities(_contracts);
70− let polls = {};
71− for (let doc of proposals) {
72− let poll = await azimuth.polls.getDocumentPoll(_contracts, doc);
73− poll.endTime = convertToInt(poll.start) + convertToInt(poll.duration);
74− poll.hasVoted = await azimuth.polls.hasVotedOnDocumentPoll(
75− _contracts,
76− _point,
77− doc
78− );
79− polls[doc] = poll;
80− }
81− setMajorities(majorities);
82− setProposals(proposals);
83− setPolls(polls);
84− setLoading(false);
85− return;
86− }, [_contracts, _point]);
87−
88− // eslint-disable-next-line
89− const [open, closed] = useMemo(() => {
90− let open = [];
91− let closed = [];
92− if (loading) return [open, closed];
93− for (let doc of proposals) {
94− if (now > polls[doc].endTime) {
95− closed.push(doc);
96− } else {
97− open.push(doc);
98− }
99− }
100− return [open, closed];
101− }, [loading, proposals, polls, now]);
6+import ViewHeader from 'components/ViewHeader';
7+import { ForwardButton } from 'components/Buttons';
1028
103− const doVote = useCallback(
104− (hash, accept) => {
105− construct(hash, accept);
106− setVotingOn({ hash, accept });
107− },
108− [construct, setVotingOn]
109− );
9+import { useLocalRouter } from 'lib/LocalRouter';
11010
111− const didVote = useCallback(() => {
112− polls[votingOn].hasVoted = true;
113− setPolls(polls);
114− setVotingOn({});
115− }, [polls, setPolls, votingOn]);
11+export default function Point() {
12+ const { pop, push, names } = useLocalRouter();
11613
117− const majorityList = useMemo(() => {
118− return majorities.map(doc => {
119− return (
120− <Grid.Item full className="mv2" as={P}>
121− <a
122− target="_blank"
123− rel="noopener noreferrer"
124− href={`https://raw.githubusercontent.com/urbit/azimuth/master/proposals/${doc}.txt`}
125− class="mb4 mono wrap pre">
126− {renderDocumentHash(doc)}↗
127− </a>
128− </Grid.Item>
129− );
130− });
131− }, [majorities]);
14+ //TODO if we moved the poll fetching logic into a cache/store,
15+ // we could be cute here and display "x ongoing" under the buttons.
13216
133− const openList = useMemo(() => {
134− return open.map(doc => {
135− const hasVoted = polls[doc].hasVoted;
136− return (
137− <>
138− <Grid.Item full className="mv2" as={Text}>
139− <P className="m0 mono wrap pre">{renderDocumentHash(doc)}</P>
140− <P className="mt0">
141− {hasVoted ? (
142− 'Your vote has been cast.'
143− ) : (
144− <>
145− <LinkButton onClick={() => doVote(doc, true)}>
146− {votingOn.hash === doc && votingOn.accept ? (
147− <b>support</b>
148− ) : (
149− <>support</>
150− )}
151− </LinkButton>
152− {' / '}
153− <LinkButton onClick={() => doVote(doc, false)}>
154− {votingOn.hash === doc && !votingOn.accept ? (
155− <b>reject</b>
156− ) : (
157− <>reject</>
158− )}
159− </LinkButton>
160− </>
161− )}
162− </P>
163− </Grid.Item>
164− <Grid.Divider />
165− </>
166− );
167− });
168− }, [open, polls, votingOn, doVote]);
17+ const goDocuments = useCallback(() => push(names.DOCUMENTS), [push, names]);
16918
170− const onDocumentChange = useCallback(({ valid, values }) => {
171− // if (values.document) {
172− // const hash = '0x' + keccak256(values.document.trim()).toString('hex');
173− // setDocumentHash(hash);
174− // } else {
175− // setDocumentHash('0x...');
176− // }
177− }, []);
19+ const goUpgrades = useCallback(() => push(names.UPGRADES), [push, names]);
17820
17921 return (
18022 <View pop={pop} inset>
181− <Grid>
182− <Grid.Item full as={ViewHeader}>
183− Senate: Document Proposals
23+ <Grid.Item full as={ViewHeader}>
24+ Senate: Proposals
25+ </Grid.Item>
26+ <Grid className="pt2">
27+ <Grid.Item
28+ full
29+ as={ForwardButton}
30+ className="mt1"
31+ onClick={goDocuments}>
32+ Document Proposals
18433 </Grid.Item>
185−
186− <Grid.Item full as={Grid}>
187− <Grid.Item full as={P}>
188− Accepted documents:
189− </Grid.Item>
190− {majorityList}
34+ <Grid.Divider />
35+ <Grid.Item full as={ForwardButton} className="mt1" onClick={goUpgrades}>
36+ Upgrade Proposals
19137 </Grid.Item>
192−
193− <Grid.Divider className="mv4" />
194−
195− <Grid.Item full as={Grid}>
196− <Grid.Item full as={P}>
197− Open document polls:
198− </Grid.Item>
199− {openList}
200− </Grid.Item>
201−
202− <BridgeForm onValues={onDocumentChange}>
203− {({ onSubmit, values }) => (
204− // <>
205− <Grid.Item
206− full
207− as={InlineEthereumTransaction}
208− {...bind}
209− onReturn={didVote}
210− />
211−
212− // <Grid.Divider />
213− //
214− // <Grid.Item
215− // full
216− // as={Input}
217− // type="textarea"
218− // placeholder="Input some text to find its hash..."
219− // name="document"
220− // className="mt4"
221− // />
222− //
223− // <Grid.Item full as={CopiableAddress}>
224− // {documentHash}
225− // </Grid.Item>
226− // </>
227− )}
228− </BridgeForm>
22938 </Grid>
23039 </View>
23140 );