resolve descriptions for proposals
This commit is contained in:
parent
489a057acb
commit
fbf91eab28
|
@ -28,6 +28,7 @@ import { PublicKey } from '@solana/web3.js'
|
||||||
import { notify } from 'utils/notifications'
|
import { notify } from 'utils/notifications'
|
||||||
import Loading from '@components/shared/Loading'
|
import Loading from '@components/shared/Loading'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import { resolveProposalDescription } from 'utils/governance/tools'
|
||||||
|
|
||||||
enum PROCESSED_VOTE_TYPE {
|
enum PROCESSED_VOTE_TYPE {
|
||||||
APPROVE,
|
APPROVE,
|
||||||
|
@ -60,10 +61,12 @@ const ProposalCard = ({
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
const [isVoteCast, setIsVoteCast] = useState(false)
|
const [isVoteCast, setIsVoteCast] = useState(false)
|
||||||
|
const [description, setDescription] = useState('')
|
||||||
|
|
||||||
const governance =
|
const governance =
|
||||||
governances && governances[proposal.account.governance.toBase58()]
|
governances && governances[proposal.account.governance.toBase58()]
|
||||||
const canVote = voter.voteWeight.cmp(new BN(1)) !== -1
|
const canVote = voter.voteWeight.cmp(new BN(1)) !== -1
|
||||||
|
const descriptionLink = proposal.account.descriptionLink
|
||||||
|
|
||||||
//Approve 0, deny 1
|
//Approve 0, deny 1
|
||||||
const vote = async (voteType: VoteKind) => {
|
const vote = async (voteType: VoteKind) => {
|
||||||
|
@ -159,6 +162,18 @@ const ProposalCard = ({
|
||||||
}
|
}
|
||||||
}, [proposal.pubkey.toBase58(), voter.tokenOwnerRecord?.pubkey.toBase58()])
|
}, [proposal.pubkey.toBase58(), voter.tokenOwnerRecord?.pubkey.toBase58()])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResolveDescription = async () => {
|
||||||
|
const description = await resolveProposalDescription(descriptionLink!)
|
||||||
|
setDescription(description)
|
||||||
|
}
|
||||||
|
if (descriptionLink) {
|
||||||
|
handleResolveDescription()
|
||||||
|
} else {
|
||||||
|
setDescription('')
|
||||||
|
}
|
||||||
|
}, [descriptionLink])
|
||||||
|
|
||||||
return governance ? (
|
return governance ? (
|
||||||
<div
|
<div
|
||||||
className="rounded-lg border border-th-bkg-3 p-4 md:p-6"
|
className="rounded-lg border border-th-bkg-3 p-4 md:p-6"
|
||||||
|
@ -174,7 +189,7 @@ const ProposalCard = ({
|
||||||
<ArrowTopRightOnSquareIcon className="mb-1 inline-block h-4 w-4 flex-shrink-0" />
|
<ArrowTopRightOnSquareIcon className="mb-1 inline-block h-4 w-4 flex-shrink-0" />
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="mb-2 md:mb-0">{proposal.account.descriptionLink}</p>
|
<p className="mb-2 md:mb-0">{description}</p>
|
||||||
</div>
|
</div>
|
||||||
<VoteCountdown
|
<VoteCountdown
|
||||||
proposal={proposal.account}
|
proposal={proposal.account}
|
||||||
|
|
|
@ -90,3 +90,52 @@ export const tryGetPubKey = (pubkey: string) => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const urlRegex =
|
||||||
|
// eslint-disable-next-line
|
||||||
|
/(https:\/\/)(gist\.github.com\/)([\w\/]{1,39}\/)([\w]{1,32})/
|
||||||
|
|
||||||
|
export async function fetchGistFile(gistUrl: string) {
|
||||||
|
const controller = new AbortController()
|
||||||
|
const pieces = gistUrl.match(urlRegex)
|
||||||
|
if (pieces) {
|
||||||
|
const justIdWithoutUser = pieces[4]
|
||||||
|
if (justIdWithoutUser) {
|
||||||
|
const apiUrl = 'https://api.github.com/gists/' + justIdWithoutUser
|
||||||
|
const apiResponse = await fetch(apiUrl, {
|
||||||
|
signal: controller.signal,
|
||||||
|
})
|
||||||
|
const jsonContent = await apiResponse.json()
|
||||||
|
if (apiResponse.status === 200) {
|
||||||
|
const nextUrlFileName = Object.keys(jsonContent['files'])[0]
|
||||||
|
const nextUrl = jsonContent['files'][nextUrlFileName]['raw_url']
|
||||||
|
if (nextUrl.startsWith('https://gist.githubusercontent.com/')) {
|
||||||
|
const fileResponse = await fetch(nextUrl, {
|
||||||
|
signal: controller.signal,
|
||||||
|
})
|
||||||
|
const body = await fileResponse.json()
|
||||||
|
//console.log('fetchGistFile file', gistUrl, fileResponse)
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
} else {
|
||||||
|
console.warn('could not fetchGistFile', {
|
||||||
|
gistUrl,
|
||||||
|
apiResponse: jsonContent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resolveProposalDescription(descriptionLink: string) {
|
||||||
|
try {
|
||||||
|
const url = new URL(descriptionLink)
|
||||||
|
const desc = (await fetchGistFile(url.toString())) ?? descriptionLink
|
||||||
|
return desc
|
||||||
|
} catch {
|
||||||
|
return descriptionLink
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue