resolve descriptions for proposals

This commit is contained in:
Adrian Brzeziński 2023-04-18 22:18:03 +02:00
parent 489a057acb
commit fbf91eab28
2 changed files with 65 additions and 1 deletions

View File

@ -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}

View File

@ -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
}
}