Skip to content

Commit

Permalink
Resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
pedromcunha committed Feb 22, 2024
2 parents 648a1cd + 106a8ec commit 5ba3dd1
Show file tree
Hide file tree
Showing 13 changed files with 755 additions and 56 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/sync-dev-branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ jobs:
sync-branches:
runs-on: ubuntu-latest
name: Syncing branches
permissions:
contents: write
steps:
- uses: actions/checkout@v2
- name: Set Git config
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/sync-env-branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ jobs:
sync-branches:
runs-on: ubuntu-latest
name: Syncing branches
permissions:
contents: write
steps:
- uses: actions/checkout@v2
- name: Set Git config
Expand Down
5 changes: 5 additions & 0 deletions components/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type Props = {
ogImage?: string
title?: string
description?: string
metatags?: React.ReactNode
}

/**
Expand All @@ -17,6 +18,7 @@ export const Head: FC<Props> = ({
ogImage = 'https://explorer.reservoir.tools/og-image.png',
title = 'Reservoir | Multi-Chain NFT Explorer',
description = 'Reservoir Multi-Chain NFT Explorer is an open source NFT explorer built with Reservoir.',
metatags = null,
}) => {
return (
<NextHead>
Expand Down Expand Up @@ -47,6 +49,9 @@ export const Head: FC<Props> = ({
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Reservoir NFT Explorer Banner" />

{/* Child Meta tags */}
{metatags && metatags}
</NextHead>
)
}
4 changes: 3 additions & 1 deletion components/primitives/CryptoCurrencyIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { styled } from '../../stitches.config'
import { StyledComponent } from '@stitches/react/types/styled-component'
import { zeroAddress } from 'viem'
import { useMarketplaceChain } from 'hooks'
import supportedChains, { DefaultChain } from 'utils/chains'

type Props = {
address: string
Expand All @@ -17,10 +18,11 @@ const CryptoCurrencyIcon: FC<Props> = ({
css,
}) => {
const { proxyApi } = useMarketplaceChain()
const chain = supportedChains.find((chain) => chain.id === chainId)

return (
<StyledImg
src={`${process.env.NEXT_PUBLIC_PROXY_URL}${proxyApi}/redirect/currency/${address}/icon/v1`}
src={`${process.env.NEXT_PUBLIC_PROXY_URL}${chain?.proxyApi ?? proxyApi}/redirect/currency/${address}/icon/v1`}
css={css}
/>
)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
"@radix-ui/react-toggle-group": "^1.0.1",
"@radix-ui/react-tooltip": "1.0.6",
"@rainbow-me/rainbowkit": "1.3.1",
"@reservoir0x/reservoir-kit-ui": "1.25.4",
"@reservoir0x/reservoir-kit-ui": "1.25.9",
"@sentry/nextjs": "^7.85.0",
"@types/uuid": "^9.0.1",
"@vercel/og": "^0.5.20",
"dayjs": "^1.11.6",
"eslint-config-next": "^14.1.0",
"framer-motion": "^6.3.6",
Expand Down
50 changes: 49 additions & 1 deletion pages/[chain]/asset/[assetId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,60 @@ const IndexPage: NextPage<Props> = ({ assetId, ssr }) => {
? token.token.name
: `${token?.token?.tokenId} - ${token?.token?.collection?.name}`

const base64EncodedToken = btoa(encodeURIComponent(JSON.stringify(token)))

return (
<Layout>
<Head
ogImage={token?.token?.image || collection?.banner}
ogImage={`/api/og/token?token=${encodeURIComponent(
base64EncodedToken
)}`}
title={pageTitle}
description={collection?.description as string}
metatags={
<>
<meta
property="og:title"
content={`Farcaster: ${token?.token?.name}`}
/>

<meta
property="eth:nft:collection"
content={`Farcaster: ${token?.token?.name}`}
/>
<meta
property="eth:nft:contract_address"
content={token?.token?.contract}
/>
<meta
property="eth:nft:creator_address"
content={token?.token?.collection?.creator}
/>
<meta
property="eth:nft:schema"
content={token?.token?.kind?.toUpperCase()}
/>
<meta property="eth:nft:media_url" content={token?.token?.image} />

<meta property="fc:frame" content="vNext" />
<meta
property="fc:frame:image"
content={token?.token?.image || collection?.banner}
/>
<meta property="fc:frame:button:1" content="Mint" />
<meta property="fc:frame:button:1:action" content="mint" />
<meta
property="fc:frame:button:1:target"
content={`eip155:${token?.token?.chainId}:${token?.token?.contract}:${token?.token?.tokenId}`}
/>
</>
}
/>
<meta
name="twitter:image"
content={`/api/og/token?token=${encodeURIComponent(
base64EncodedToken
)}`}
/>
<Flex
justify="center"
Expand Down
40 changes: 40 additions & 0 deletions pages/[chain]/collection/[contract].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
useCollectionActivity,
useDynamicTokens,
useAttributes,
useReservoirClient,
} from '@reservoir0x/reservoir-kit-ui'
import { paths } from '@reservoir0x/reservoir-sdk'
import Layout from 'components/Layout'
Expand Down Expand Up @@ -81,6 +82,7 @@ const CollectionPage: NextPage<Props> = ({ id, ssr }) => {
const [activityFiltersOpen, setActivityFiltersOpen] = useState(true)
const [tokenSearchQuery, setTokenSearchQuery] = useState<string>('')
const chainCurrency = useChainCurrency()
const client = useReservoirClient()
const debouncedSearch = useDebounce(tokenSearchQuery, 500)
const [socketState, setSocketState] = useState<SocketState>(null)
const [activityTypes, setActivityTypes] = useState<ActivityTypes>([
Expand Down Expand Up @@ -359,6 +361,44 @@ const CollectionPage: NextPage<Props> = ({ id, ssr }) => {
ogImage={ssr?.collection?.collections?.[0]?.banner}
title={ssr?.collection?.collections?.[0]?.name}
description={ssr?.collection?.collections?.[0]?.description as string}
metatags={
<>
<meta property="eth:nft:collection" content={collection.name} />
<meta
property="eth:nft:contract_address"
content={collection.primaryContract}
/>
<meta
property="eth:nft:creator_address"
content={collection.primaryContract}
/>
<meta
property="eth:nft:schema"
content={collection.contractKind?.toLowerCase()}
/>
<meta
property="eth:nft:mint_status"
content={collection.isMinting ? 'live' : 'closed'}
/>
<meta
property="eth:nft:chain"
content={client?.currentChain()?.name}
/>
<meta property="nft:chain" content={client?.currentChain()?.name} />
<meta property="fc:frame" content="vNext" />
<meta
property="fc:frame:image"
content={collection.image || collection.banner}
/>
<meta property="fc:frame:image:aspect_ratio" content="1:1" />
<meta property="fc:frame:button:1" content="Mint" />
<meta property="fc:frame:button:1:action" content="mint" />
<meta
property="fc:frame:button:1:target"
content={`eip155:${collection.chainId}:${collection.primaryContract}`}
/>
</>
}
/>
<Tabs.Root
defaultValue="items"
Expand Down
63 changes: 45 additions & 18 deletions pages/api/globalSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ export const config = {
runtime: 'edge',
}

const spamCollections: Record<number, string[]> = {
1: ['0x31fe9d95dde43cf9893b76160f63521a9e3d26b0'],
}

const locallyFilterSpam = (results: any[]) => {
return results.filter((result) => {
if (
result.data.collectionId &&
result.data.chainId &&
spamCollections[result.data.chainId]
) {
return !spamCollections[result.data.chainId].includes(
result.data.collectionId
)
? true
: false
} else {
return true
}
})
}

export default async function handler(req: Request) {
const { searchParams } = new URL(req.url)
const query = searchParams.get('query')
Expand All @@ -39,7 +61,7 @@ export default async function handler(req: Request) {

if (searchChain) {
const chain = supportedChains.find(
(chain) => chain.routePrefix === searchChain,
(chain) => chain.routePrefix === searchChain
)

if (chain) {
Expand All @@ -62,7 +84,7 @@ export default async function handler(req: Request) {
'content-type': 'application/json',
'Cache-Control': 'maxage=0, s-maxage=3600 stale-while-revalidate',
},
},
}
)
}

Expand All @@ -89,7 +111,7 @@ async function searchSingleChain(chain: ReservoirChain, query: string) {
const promise = fetcher(
`${reservoirBaseUrl}/search/collections/v1`,
queryData,
headers,
headers
)
promise.catch((e: any) => console.warn('Failed to search', e))

Expand All @@ -100,7 +122,7 @@ async function searchSingleChain(chain: ReservoirChain, query: string) {
const { data } = await fetcher(
`${reservoirBaseUrl}/collections/v7?contract=${query}&limit=6`,
{},
headers,
headers
)
if (data.collections.length > 0) {
const processedCollections = data.collections.map(
Expand All @@ -126,14 +148,14 @@ async function searchSingleChain(chain: ReservoirChain, query: string) {
type: 'collection',
data: processedCollection,
}
},
}
)
searchResults = processedCollections
}
// if ethereum chain
else if (chain.id === 1) {
let ensData = await fetch(
`https://api.ensideas.com/ens/resolve/${query}`,
`https://api.ensideas.com/ens/resolve/${query}`
).then((res) => res.json())
searchResults = [
{
Expand All @@ -150,11 +172,11 @@ async function searchSingleChain(chain: ReservoirChain, query: string) {
else if (
chain.id === 1 &&
/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi.test(
query as string,
query as string
)
) {
let ensData = await fetch(
`https://api.ensideas.com/ens/resolve/${query}`,
`https://api.ensideas.com/ens/resolve/${query}`
).then((res) => res.json())

if (ensData.address) {
Expand Down Expand Up @@ -186,11 +208,13 @@ async function searchSingleChain(chain: ReservoirChain, query: string) {
tokenCount: collection.tokenCount,
allTimeUsdVolume: collection.allTimeVolume,
},
}),
})
)
searchResults = processedSearchResults
}
}
//filter own known spam collections
searchResults = locallyFilterSpam(searchResults)
return searchResults
}

Expand Down Expand Up @@ -223,7 +247,7 @@ async function searchAllChains(query: string) {
const promise = fetcher(
`${reservoirBaseUrl}/search/collections/v1`,
query,
headers,
headers
)
promise.catch((e: any) => console.warn('Failed to search', e))
promises.push(promise)
Expand All @@ -242,7 +266,7 @@ async function searchAllChains(query: string) {
const { data } = await fetcher(
`${reservoirBaseUrl}/collections/v7?contract=${query}&limit=6`,
{},
headers,
headers
)
return data.collections.map((collection: Collection) => {
const processedCollection: SearchCollection = {
Expand Down Expand Up @@ -271,7 +295,7 @@ async function searchAllChains(query: string) {
let results = await Promise.allSettled(promises).then((results) => {
return results
.filter(
(result) => result.status === 'fulfilled' && result.value.length > 0,
(result) => result.status === 'fulfilled' && result.value.length > 0
)
.flatMap((result) => (result as PromiseFulfilledResult<any>).value)
})
Expand All @@ -280,7 +304,7 @@ async function searchAllChains(query: string) {
searchResults = results
} else {
let ensData = await fetch(
`https://api.ensideas.com/ens/resolve/${query}`,
`https://api.ensideas.com/ens/resolve/${query}`
).then((res) => res.json())
searchResults = [
{
Expand All @@ -294,11 +318,11 @@ async function searchAllChains(query: string) {
}
} else if (
/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi.test(
query as string,
query as string
)
) {
let ensData = await fetch(
`https://api.ensideas.com/ens/resolve/${query}`,
`https://api.ensideas.com/ens/resolve/${query}`
).then((res) => res.json())

if (ensData.address) {
Expand All @@ -314,7 +338,7 @@ async function searchAllChains(query: string) {
} else {
// Get current usd prices for each chain
const usdCoinPrices = await fetch(`${HOST_URL}/api/usdCoinConversion`).then(
(res) => res.json(),
(res) => res.json()
)

const responses = await Promise.allSettled(promises)
Expand Down Expand Up @@ -342,17 +366,20 @@ async function searchAllChains(query: string) {
usdCoinPrices?.prices?.[index]?.current_price) ||
0,
},
}),
})
)
searchResults = [...searchResults, ...chainSearchResults]
})

// Sort results by all time usd volume only if usdCoinPrices is not null
if (usdCoinPrices) {
searchResults = searchResults.sort(
(a, b) => b.data.allTimeUsdVolume - a.data.allTimeUsdVolume,
(a, b) => b.data.allTimeUsdVolume - a.data.allTimeUsdVolume
)
}

//filter own known spam collections
searchResults = locallyFilterSpam(searchResults)
}

return searchResults
Expand Down
Loading

0 comments on commit 5ba3dd1

Please sign in to comment.