Merge pull request #128 from blockworks-foundation/feature/resolve-proposal-description
resolve descriptions for proposals
This commit is contained in:
commit
66a5a2e5ea
|
@ -28,6 +28,7 @@ import { PublicKey } from '@solana/web3.js'
|
|||
import { notify } from 'utils/notifications'
|
||||
import Loading from '@components/shared/Loading'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { resolveProposalDescription } from 'utils/governance/tools'
|
||||
|
||||
enum PROCESSED_VOTE_TYPE {
|
||||
APPROVE,
|
||||
|
@ -60,10 +61,12 @@ const ProposalCard = ({
|
|||
null
|
||||
)
|
||||
const [isVoteCast, setIsVoteCast] = useState(false)
|
||||
const [description, setDescription] = useState('')
|
||||
|
||||
const governance =
|
||||
governances && governances[proposal.account.governance.toBase58()]
|
||||
const canVote = voter.voteWeight.cmp(new BN(1)) !== -1
|
||||
const descriptionLink = proposal.account.descriptionLink
|
||||
|
||||
//Approve 0, deny 1
|
||||
const vote = async (voteType: VoteKind) => {
|
||||
|
@ -159,6 +162,18 @@ const ProposalCard = ({
|
|||
}
|
||||
}, [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 ? (
|
||||
<div
|
||||
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" />
|
||||
</a>
|
||||
</h2>
|
||||
<p className="mb-2 md:mb-0">{proposal.account.descriptionLink}</p>
|
||||
<p className="mb-2 md:mb-0">{description}</p>
|
||||
</div>
|
||||
<VoteCountdown
|
||||
proposal={proposal.account}
|
||||
|
|
|
@ -90,3 +90,52 @@ export const tryGetPubKey = (pubkey: string) => {
|
|||
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