diff --git a/contracts/tasks/runners/exportImages.ts b/contracts/tasks/runners/exportImages.ts index 56f04e678..46a782362 100644 --- a/contracts/tasks/runners/exportImages.ts +++ b/contracts/tasks/runners/exportImages.ts @@ -12,8 +12,8 @@ */ import { task } from 'hardhat/config' -import { FetchRequest } from 'ethers' import { isPathExist, makeDirectory } from '../../utils/misc' +import { getIpfsContent } from '@clrfund/common' import fs from 'fs' /** @@ -31,11 +31,11 @@ async function download({ ipfsHash: string outputDir: string }) { - const url = new URL(`ipfs/${ipfsHash}`, gateway) - const req = new FetchRequest(url.href) - const res = await req.send() + if (!ipfsHash) return + + const res = await getIpfsContent(ipfsHash, gateway) if (res.hasBody()) { - console.log('Downloading', ipfsHash) + console.log('Downloaded', ipfsHash) fs.writeFileSync(`${outputDir}/${ipfsHash}`, res.body) } } diff --git a/vue-app/src/api/projects.ts b/vue-app/src/api/projects.ts index 2795ad82e..4df82be0b 100644 --- a/vue-app/src/api/projects.ts +++ b/vue-app/src/api/projects.ts @@ -14,9 +14,8 @@ export interface LeaderboardProject { id: string // Address or another ID depending on registry implementation name: string index: number - bannerImageUrl?: string - thumbnailImageUrl?: string - imageUrl?: string + bannerImageHash?: string + thumbnailImageHash?: string allocatedAmount: bigint votes: bigint donation: bigint @@ -39,9 +38,8 @@ export interface Project { websiteUrl?: string twitterUrl?: string discordUrl?: string - bannerImageUrl?: string - thumbnailImageUrl?: string - imageUrl?: string // TODO remove + bannerImageHash?: string + thumbnailImageHash?: string index: number isHidden: boolean // Hidden from the list (does not participate in round) isLocked: boolean // Visible, but contributions are not allowed @@ -134,17 +132,13 @@ export async function getProjectByIndex( metadata = {} } - const thumbnailImageUrl = metadata.thumbnailImageHash - ? `${ipfsGatewayUrl}/ipfs/${metadata.thumbnailImageHash}` - : `${ipfsGatewayUrl}/ipfs/${metadata.imageUrl}` - return { id: recipient.id, address: recipient.recipientAddress || '', name: metadata.name, description: metadata.description, tagline: metadata.tagline, - thumbnailImageUrl, + thumbnailImageHash: metadata.thumbnailImageHash || metadata.imageHash, index: recipient.recipientIndex, } } @@ -182,12 +176,12 @@ export async function getRecipientIdByHash(transactionHash: string): Promise project.id === projectId) const metadata = project.metadata - const thumbnailHash = metadata.thumbnailImageHash || metadata.imageHash - const thumbnailImageUrl = thumbnailHash ? `${ipfsGatewayUrl}/ipfs/${thumbnailHash}` : undefined - const bannerHash = metadata.bannerImageHash || metadata.imageHash - const bannerImageUrl = bannerHash ? `${ipfsGatewayUrl}/ipfs/${bannerHash}` : undefined + const thumbnailImageHash = metadata.thumbnailImageHash || metadata.imageHash + const bannerImageHash = metadata.bannerImageHash || metadata.imageHash return { id: project.id, @@ -228,8 +220,8 @@ export async function getLeaderboardProject( websiteUrl: metadata.websiteUrl, twitterUrl: metadata.twitterUrl, discordUrl: metadata.discordUrl, - thumbnailImageUrl, - bannerImageUrl, + thumbnailImageHash, + bannerImageHash, index: project.recipientIndex, isHidden: false, // always show leaderboard project isLocked: true, // Visible, but contributions are not allowed @@ -254,8 +246,8 @@ export function formToProjectInterface(data: RecipientApplicationData): Project websiteUrl: links.website, twitterUrl: links.twitter, discordUrl: links.discord, - bannerImageUrl: `${ipfsGatewayUrl}/ipfs/${image.bannerHash}`, - thumbnailImageUrl: `${ipfsGatewayUrl}/ipfs/${image.thumbnailHash}`, + bannerImageHash: image.bannerHash, + thumbnailImageHash: image.thumbnailHash, index: 0, isHidden: false, isLocked: true, @@ -284,8 +276,8 @@ export function staticDataToProjectInterface(project: any): Project { websiteUrl: project.metadata.websiteUrl, twitterUrl: project.metadata.twitterUrl, discordUrl: project.discordUrl, - bannerImageUrl: `${ipfsGatewayUrl}/ipfs/${project.metadata.bannerImageHash}`, - thumbnailImageUrl: `${ipfsGatewayUrl}/ipfs/${project.metadata.thumbnailImageHash}`, + bannerImageHash: project.metadata.bannerImageHash, + thumbnailImageHash: project.metadata.thumbnailImageHash, index: project.recipientIndex, isHidden: project.state !== 'Accepted', isLocked: false, diff --git a/vue-app/src/api/recipient-registry-kleros.ts b/vue-app/src/api/recipient-registry-kleros.ts index 7ab229938..943a6e149 100644 --- a/vue-app/src/api/recipient-registry-kleros.ts +++ b/vue-app/src/api/recipient-registry-kleros.ts @@ -39,7 +39,7 @@ function decodeTcrItemData( address: string name: string description: string - imageUrl: string + imageHash: string } { // Disable console.error to ignore parser errors /* eslint-disable no-console */ @@ -52,7 +52,7 @@ function decodeTcrItemData( address: decodedMetadata[1] as string, name: decodedMetadata[0] as string, description: decodedMetadata[3] as string, - imageUrl: `${ipfsGatewayUrl}${decodedMetadata[2]}`, + imageHash: decodedMetadata[2] as string, } } diff --git a/vue-app/src/api/recipient-registry-optimistic.ts b/vue-app/src/api/recipient-registry-optimistic.ts index 1baf6610f..70cb01bad 100644 --- a/vue-app/src/api/recipient-registry-optimistic.ts +++ b/vue-app/src/api/recipient-registry-optimistic.ts @@ -70,8 +70,8 @@ export enum RequestStatus { interface RecipientMetadata { name: string description: string - imageUrl: string - thumbnailImageUrl: string + imageHash: string + thumbnailImageHash: string } export interface Request { @@ -155,10 +155,8 @@ export async function getRequests(registryInfo: RegistryInfo, registryAddress: s metadata = { name, description, - imageUrl: `${ipfsGatewayUrl}/ipfs/${imageHash}`, - thumbnailImageUrl: thumbnailImageHash - ? `${ipfsGatewayUrl}/ipfs/${thumbnailImageHash}` - : `${ipfsGatewayUrl}/ipfs/${imageHash}`, + imageHash: imageHash, + thumbnailImageHash: thumbnailImageHash, } } @@ -213,9 +211,6 @@ function decodeProject(recipient: Partial): Project { const metadata = JSON.parse(recipient.recipientMetadata || '') - // imageUrl is the legacy form property - fall back to this if bannerImageHash or thumbnailImageHash don't exist - const imageUrl = `${ipfsGatewayUrl}/ipfs/${metadata.imageHash}` - let requester if (recipient.requester) { requester = recipient.requester @@ -227,7 +222,6 @@ function decodeProject(recipient: Partial): Project { requester, name: metadata.name, description: metadata.description, - imageUrl, // Only unregistered project can have invalid index 0 index: 0, isHidden: false, @@ -246,8 +240,8 @@ function decodeProject(recipient: Partial): Project { websiteUrl: metadata.websiteUrl, twitterUrl: metadata.twitterUrl, discordUrl: metadata.discordUrl, - bannerImageUrl: metadata.bannerImageHash ? `${ipfsGatewayUrl}/ipfs/${metadata.bannerImageHash}` : imageUrl, - thumbnailImageUrl: metadata.thumbnailImageHash ? `${ipfsGatewayUrl}/ipfs/${metadata.thumbnailImageHash}` : imageUrl, + bannerImageHash: metadata.bannerImageHash || metadata.imageHash, + thumbnailImageHash: metadata.thumbnailImageHash || metadata.imageHash, } } diff --git a/vue-app/src/api/recipient-registry-simple.ts b/vue-app/src/api/recipient-registry-simple.ts index 8b8f581db..fd988e92a 100644 --- a/vue-app/src/api/recipient-registry-simple.ts +++ b/vue-app/src/api/recipient-registry-simple.ts @@ -27,8 +27,8 @@ function decodeRecipientAdded(event: EventLog): Project { websiteUrl: metadata.websiteUrl, twitterUrl: metadata.twitterUrl, discordUrl: metadata.discordUrl, - bannerImageUrl: `${ipfsGatewayUrl}/ipfs/${metadata.bannerImageHash}`, - thumbnailImageUrl: `${ipfsGatewayUrl}/ipfs/${metadata.thumbnailImageHash}`, + bannerImageHash: metadata.bannerImageHash, + thumbnailImageHash: metadata.thumbnailImageHash, index: getNumber(args._index), isHidden: false, isLocked: false, diff --git a/vue-app/src/components.d.ts b/vue-app/src/components.d.ts index 5f037b3de..49476f1ad 100644 --- a/vue-app/src/components.d.ts +++ b/vue-app/src/components.d.ts @@ -36,6 +36,7 @@ declare module '@vue/runtime-core' { Info: typeof import('./components/Info.vue')['default'] InputButton: typeof import('./components/InputButton.vue')['default'] IpfsCopyWidget: typeof import('./components/IpfsCopyWidget.vue')['default'] + IpfsImage: typeof import('./components/IpfsImage.vue')['default'] IpfsImageUpload: typeof import('./components/IpfsImageUpload.vue')['default'] LayoutSteps: typeof import('./components/LayoutSteps.vue')['default'] LeaderboardDetailView: typeof import('./components/LeaderboardDetailView.vue')['default'] diff --git a/vue-app/src/components/CartItems.vue b/vue-app/src/components/CartItems.vue index 915a09f58..e2081542e 100644 --- a/vue-app/src/components/CartItems.vue +++ b/vue-app/src/components/CartItems.vue @@ -10,7 +10,7 @@ >
- + {{ item.name }} diff --git a/vue-app/src/components/IpfsImage.vue b/vue-app/src/components/IpfsImage.vue new file mode 100644 index 000000000..70f3b226f --- /dev/null +++ b/vue-app/src/components/IpfsImage.vue @@ -0,0 +1,25 @@ + + + diff --git a/vue-app/src/components/LeaderboardSimpleView.vue b/vue-app/src/components/LeaderboardSimpleView.vue index 5ffe65266..75605794e 100644 --- a/vue-app/src/components/LeaderboardSimpleView.vue +++ b/vue-app/src/components/LeaderboardSimpleView.vue @@ -25,7 +25,7 @@
- +
{{ project.name }} @@ -49,6 +49,7 @@ import type { LeaderboardProject } from '@/api/projects' import type { RoundInfo } from '@/api/round' import { formatAmount } from '@/utils/amounts' +import { getStaticAssetsUrlByIpfsHash, getIpfsUrl } from '@/utils/url' interface Props { project: LeaderboardProject @@ -79,14 +80,6 @@ function formatAllocationAmount(amount?: bigint): string { return amount ? formatAmount(amount, tokenDecimals, null, 0) : '0' } -const projectImageUrl = computed(() => { - if (typeof props.project.imageUrl !== 'undefined') { - return props.project.imageUrl - } - - return null -}) - const tokenSymbol = computed(() => { return props.round.nativeTokenSymbol }) diff --git a/vue-app/src/components/ProjectListItem.vue b/vue-app/src/components/ProjectListItem.vue index 009502493..04282b1da 100644 --- a/vue-app/src/components/ProjectListItem.vue +++ b/vue-app/src/components/ProjectListItem.vue @@ -3,7 +3,7 @@
- +
{{ $t(categoryLocaleKey(project.category)) }}
@@ -37,6 +37,7 @@ import { useRoute, type RouteLocationRaw } from 'vue-router' import { useAppStore } from '@/stores' import { storeToRefs } from 'pinia' import { isActiveApp } from '@/api/core' +import IpfsImage from './IpfsImage.vue' const route = useRoute() const appStore = useAppStore() @@ -55,16 +56,6 @@ const descriptionHtml = computed(() => { return markdown.renderInline(props.project.description) }) -const projectImageUrl = computed(() => { - if (typeof props.project.bannerImageUrl !== 'undefined') { - return props.project.bannerImageUrl - } - if (typeof props.project.imageUrl !== 'undefined') { - return props.project.imageUrl - } - return null -}) - const inCart = computed(() => { const index = appStore.cart.findIndex((item: CartItem) => { // Ignore cleared items diff --git a/vue-app/src/components/ProjectProfile.vue b/vue-app/src/components/ProjectProfile.vue index 1bdc167ed..eaa233143 100644 --- a/vue-app/src/components/ProjectProfile.vue +++ b/vue-app/src/components/ProjectProfile.vue @@ -1,7 +1,7 @@