Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QA bug fixes #1315

Merged
merged 6 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 22 additions & 28 deletions src/components/Proposals/ProposalActions/ProposalAction.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { Button, Flex, Text } from '@chakra-ui/react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { BACKGROUND_SEMI_TRANSPARENT } from '../../../constants/common';
import { DAO_ROUTES } from '../../../constants/routes';
import useSnapshotProposal from '../../../hooks/DAO/loaders/snapshot/useSnapshotProposal';
import { useFractal } from '../../../providers/App/AppProvider';
import {
ExtendedSnapshotProposal,
FractalProposal,
FractalProposalState,
SnapshotProposal,
} from '../../../types';
import { ExtendedSnapshotProposal, FractalProposal, FractalProposalState } from '../../../types';
import ContentBox from '../../ui/containers/ContentBox';
import { ProposalCountdown } from '../../ui/proposal/ProposalCountdown';
import { useVoteContext } from '../ProposalVotes/context/VoteContext';
Expand Down Expand Up @@ -60,7 +55,6 @@ export function ProposalAction({
node: { daoAddress },
readOnly: { user, dao },
} = useFractal();
const { push } = useRouter();
const { t } = useTranslation();
const { isSnapshotProposal } = useSnapshotProposal(proposal);
const { canVote } = useVoteContext();
Expand All @@ -78,16 +72,6 @@ export function ProposalAction({
proposal.state === FractalProposalState.TIMELOCKABLE ||
proposal.state === FractalProposalState.TIMELOCKED));

const handleClick = () => {
if (isSnapshotProposal) {
push(
DAO_ROUTES.proposal.relative(daoAddress, (proposal as SnapshotProposal).snapshotProposalId)
);
} else {
push(DAO_ROUTES.proposal.relative(daoAddress, proposal.proposalId));
}
};

const labelKey = useMemo(() => {
switch (proposal.state) {
case FractalProposalState.ACTIVE:
Expand Down Expand Up @@ -119,12 +103,17 @@ export function ProposalAction({
if (!showActionButton) {
if (!expandedView) {
return (
<Button
variant="secondary"
onClick={handleClick}
<Link
href={DAO_ROUTES.proposal.relative(daoAddress, proposal.proposalId)}
passHref
>
{t('details')}
</Button>
<Button
as="a"
variant="secondary"
>
{t('details')}
</Button>
</Link>
);
}
// This means that Proposal in state where there's no action to perform
Expand Down Expand Up @@ -155,11 +144,16 @@ export function ProposalAction({
}

return (
<Button
onClick={handleClick}
variant={showActionButton && canVote ? 'primary' : 'secondary'}
<Link
href={DAO_ROUTES.proposal.relative(daoAddress, proposal.proposalId)}
passHref
>
{label}
</Button>
<Button
as="a"
variant={showActionButton && canVote ? 'primary' : 'secondary'}
>
{label}
</Button>
</Link>
);
}
10 changes: 4 additions & 6 deletions src/components/Proposals/ProposalInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, Text, Image, Button } from '@chakra-ui/react';
import { Box, Flex, Text, Image, Button, Link } from '@chakra-ui/react';
import { Shield } from '@decent-org/fractal-ui';
import { useTranslation } from 'react-i18next';
import useSnapshotProposal from '../../hooks/DAO/loaders/snapshot/useSnapshotProposal';
Expand Down Expand Up @@ -41,14 +41,12 @@ export function ProposalInfo({
/>
{(proposal as ExtendedSnapshotProposal).privacy === 'shutter' && (
<Button
as={Link}
target="_blank"
href="https://blog.shutter.network/announcing-shutter-governance-shielded-voting-for-daos/"
variant="secondary"
h={6}
w={32}
onClick={() =>
window.open(
'https://blog.shutter.network/announcing-shutter-governance-shielded-voting-for-daos/'
)
}
>
<Shield
width="16px"
Expand Down
19 changes: 6 additions & 13 deletions src/components/ui/badges/Snapshot.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Button, ButtonProps, Image } from '@chakra-ui/react';
import { ArrowAngleUp } from '@decent-org/fractal-ui';
import { Button, ButtonProps, Image, Link } from '@chakra-ui/react';
import { t } from 'i18next';

interface Props extends ButtonProps {
snapshotURL: string;
isExternal?: boolean;
}

export default function Snapshot({ snapshotURL, isExternal, ...rest }: Props) {
export default function Snapshot({ snapshotURL, ...rest }: Props) {
return (
<Button
onClick={() => window.open(`https://snapshot.org/#/${snapshotURL}`)}
href={snapshotURL}
as={Link}
target="_blank"
variant="secondary"
mt={5}
h={6}
w={isExternal ? 40 : 32}
w={32}
{...rest}
>
<>
Expand All @@ -24,13 +24,6 @@ export default function Snapshot({ snapshotURL, isExternal, ...rest }: Props) {
mr={1}
/>
{t('snapshot')}
{isExternal && (
<ArrowAngleUp
width="24px"
height="24px"
ml={1}
/>
)}
</>
</Button>
);
Expand Down
13 changes: 6 additions & 7 deletions src/hooks/DAO/loaders/snapshot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ const defaultOptions: DefaultOptions = {
},
};

const client = new ApolloClient({
uri: 'https://hub.snapshot.org/graphql',
cache: new InMemoryCache(),
defaultOptions,
});

export default client;
export const createClient = (uri: string) =>
new ApolloClient({
uri: `https://${uri.includes('testnet') ? 'testnet.' : ''}hub.snapshot.org/graphql`,
cache: new InMemoryCache(),
defaultOptions,
});
35 changes: 24 additions & 11 deletions src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { gql } from '@apollo/client';
import { useCallback, useMemo, useState } from 'react';
import { logError } from '../../../../helpers/errorLogging';
import { useFractal } from '../../../../providers/App/AppProvider';
import {
ExtendedSnapshotProposal,
Expand All @@ -9,7 +10,8 @@ import {
SnapshotVote,
SnapshotWeightedVotingChoice,
} from '../../../../types';
import client from './';
import useSnapshotSpaceName from './useSnapshotSpaceName';
import { createClient } from './';

export default function useSnapshotProposal(proposal: FractalProposal | null | undefined) {
const [extendedSnapshotProposal, setExtendedSnapshotProposal] =
Expand All @@ -20,6 +22,12 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u
user: { address },
},
} = useFractal();
const daoSnapshotSpaceName = useSnapshotSpaceName();
const client = useMemo(() => {
if (daoSnapshotURL) {
return createClient(daoSnapshotURL);
}
}, [daoSnapshotURL]);

const snapshotProposal = proposal as SnapshotProposal;
const isSnapshotProposal = useMemo(
Expand All @@ -28,7 +36,7 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u
);

const loadProposal = useCallback(async () => {
if (snapshotProposal?.snapshotProposalId) {
if (snapshotProposal?.snapshotProposalId && client) {
const proposalQueryResult = await client
.query({
query: gql`
Expand Down Expand Up @@ -188,17 +196,22 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u
votes: votesQueryResult,
} as ExtendedSnapshotProposal);
}
}, [snapshotProposal?.snapshotProposalId, proposal, snapshotProposal?.state]);
}, [snapshotProposal?.snapshotProposalId, proposal, snapshotProposal?.state, client]);

const loadVotingWeight = useCallback(async () => {
if (snapshotProposal?.snapshotProposalId) {
const emptyVotingWeight = {
votingWeight: 0,
votingWeightByStrategy: [0],
votingState: '',
};
if (snapshotProposal?.snapshotProposalId && client) {
const queryResult = await client
.query({
query: gql`
query UserVotingWeight {
vp(
voter: "${address}"
space: "${daoSnapshotURL}"
space: "${daoSnapshotSpaceName}"
proposal: "${snapshotProposal.snapshotProposalId}"
) {
vp
Expand All @@ -208,6 +221,10 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u
}`,
})
.then(({ data: { vp } }) => {
if (!vp) {
logError('Error while retrieving Snapshot voting weight', vp);
return emptyVotingWeight;
}
return {
votingWeight: vp.vp,
votingWeightByStrategy: vp.vp_by_strategy,
Expand All @@ -218,12 +235,8 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u
return queryResult;
}

return {
votingWeight: 0,
votingWeightByStrategy: [0],
votingState: '',
};
}, [address, daoSnapshotURL, snapshotProposal?.snapshotProposalId]);
return emptyVotingWeight;
}, [address, snapshotProposal?.snapshotProposalId, client, daoSnapshotSpaceName]);

return {
loadVotingWeight,
Expand Down
79 changes: 44 additions & 35 deletions src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { gql } from '@apollo/client';
import { useCallback, useEffect, useRef } from 'react';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useFractal } from '../../../../providers/App/AppProvider';
import { FractalGovernanceAction } from '../../../../providers/App/governance/action';
import { ActivityEventType, FractalProposalState } from '../../../../types';
import { SnapshotProposal } from '../../../../types/daoProposal';
import client from './';
import useSnapshotSpaceName from './useSnapshotSpaceName';
import { createClient } from './';

export const useSnapshotProposals = () => {
const {
node: { daoSnapshotURL },
action,
} = useFractal();
const daoSnapshotSpaceName = useSnapshotSpaceName();
const currentSnapshotURL = useRef<string | undefined>();
const client = useMemo(() => {
if (daoSnapshotURL) {
return createClient(daoSnapshotURL);
}
}, [daoSnapshotURL]);

const loadSnapshotProposals = useCallback(async () => {
client
.query({
query: gql`
if (client) {
client
.query({
query: gql`
query Proposals {
proposals(
first: 50,
where: {
space_in: ["${daoSnapshotURL}"]
space_in: ["${daoSnapshotSpaceName}"]
},
orderBy: "created",
orderDirection: desc
Expand All @@ -42,39 +50,40 @@ export const useSnapshotProposals = () => {
}
}
`,
})
.then(result => {
const proposals: SnapshotProposal[] = result.data.proposals.map((proposal: any) => {
return {
eventDate: new Date(proposal.start * 1000),
eventType: ActivityEventType.Governance,
state:
proposal.state === 'active'
? FractalProposalState.ACTIVE
: proposal.state === 'closed'
? FractalProposalState.CLOSED
: FractalProposalState.PENDING,
})
.then(result => {
const proposals: SnapshotProposal[] = result.data.proposals.map((proposal: any) => {
return {
eventDate: new Date(proposal.start * 1000),
eventType: ActivityEventType.Governance,
state:
proposal.state === 'active'
? FractalProposalState.ACTIVE
: proposal.state === 'closed'
? FractalProposalState.CLOSED
: FractalProposalState.PENDING,

proposalId: proposal.id,
snapshotProposalId: proposal.id,
targets: [],
title: proposal.title,
description: proposal.body,
startTime: proposal.start,
endTime: proposal.end,
};
});
proposalId: proposal.id,
snapshotProposalId: proposal.id,
targets: [],
title: proposal.title,
description: proposal.body,
startTime: proposal.start,
endTime: proposal.end,
};
});

action.dispatch({
type: FractalGovernanceAction.SET_SNAPSHOT_PROPOSALS,
payload: proposals,
action.dispatch({
type: FractalGovernanceAction.SET_SNAPSHOT_PROPOSALS,
payload: proposals,
});
});
});
}, [action, daoSnapshotURL]);
}
}, [action, daoSnapshotSpaceName, client]);

useEffect(() => {
if (!daoSnapshotURL || daoSnapshotURL === currentSnapshotURL.current) return;
currentSnapshotURL.current = daoSnapshotURL;
if (!daoSnapshotSpaceName || daoSnapshotSpaceName === currentSnapshotURL.current) return;
currentSnapshotURL.current = daoSnapshotSpaceName;
loadSnapshotProposals();
}, [daoSnapshotURL, loadSnapshotProposals]);
}, [daoSnapshotSpaceName, loadSnapshotProposals]);
};
9 changes: 9 additions & 0 deletions src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useFractal } from '../../../../providers/App/AppProvider';

export default function useSnapshotSpaceName() {
const {
node: { daoSnapshotURL },
} = useFractal();

return daoSnapshotURL?.split('/').pop();
}
Loading