From 14b6c479522aeadc9cd06600d7a9d59451020257 Mon Sep 17 00:00:00 2001 From: Andrea Franz Date: Tue, 6 Feb 2024 12:45:56 +0100 Subject: [PATCH 1/2] explorer: enable markdown for any type of answer in round applications (#2886) * explorer: enable markdown for any type of answer in round applications * update global css to use regular weight * add full URL to github/twitter links in application page --- .../src/features/round/ViewProjectDetails.tsx | 53 +++++++++++-------- packages/grant-explorer/src/index.css | 4 +- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/packages/grant-explorer/src/features/round/ViewProjectDetails.tsx b/packages/grant-explorer/src/features/round/ViewProjectDetails.tsx index b65e652e85..400f42b883 100644 --- a/packages/grant-explorer/src/features/round/ViewProjectDetails.tsx +++ b/packages/grant-explorer/src/features/round/ViewProjectDetails.tsx @@ -213,7 +213,9 @@ export default function ViewProjectDetails() { onChange={handleTabChange} tabs={projectDetailsTabs.map((tab) => tab.name)} /> -
{projectDetailsTabs[selectedTab].content}
+
+ {projectDetailsTabs[selectedTab].content} +
@@ -309,23 +311,29 @@ function ProjectLinks({ project }: { project?: Project }) { {website} - - {projectTwitter} - - - {projectGithub} - - - {userGithub} - + {projectTwitter !== undefined && ( + + {projectTwitter} + + )} + {projectGithub !== undefined && ( + + {projectGithub} + + )} + {userGithub !== undefined && ( + + {userGithub} + + )} ); } @@ -412,9 +420,12 @@ function ApplicationFormAnswers(props: { className="text-md prose prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-a:text-blue-600" >

) : ( -

- {answerText.replace(/\n/g, "
")} -

+

)} ); diff --git a/packages/grant-explorer/src/index.css b/packages/grant-explorer/src/index.css index dbc667f1ea..c45424e9ad 100644 --- a/packages/grant-explorer/src/index.css +++ b/packages/grant-explorer/src/index.css @@ -2,7 +2,7 @@ @import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&display=swap'); @font-face { - font-family: "Modern Era Regular"; + font-family: "Modern Era"; font-weight: 400; src: local("ModernEraRegular"), url("../public/modern-era-regular.otf") format('opentype'); @@ -16,7 +16,7 @@ } @font-face { - font-family: "Modern Era"; + font-family: "Modern Era Bold"; font-weight: 600; src: local("ModernEraBold"), url("../public/modern-era-bold.otf") format('opentype'); From 6a0d6f24b0681fd0e5adba67af946aea7324b089 Mon Sep 17 00:00:00 2001 From: Andrea Franz Date: Tue, 6 Feb 2024 17:39:33 +0100 Subject: [PATCH 2/2] data-layer: filter out spam rounds based on a temporary csv blacklist (#2893) * data-layer: filter out spam rounds based on a temporary csv blacklist * fix rounds spam filtering --- packages/data-layer/src/backends/legacy.ts | 61 +++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/packages/data-layer/src/backends/legacy.ts b/packages/data-layer/src/backends/legacy.ts index 37f2b16f78..c90ad0ebe3 100644 --- a/packages/data-layer/src/backends/legacy.ts +++ b/packages/data-layer/src/backends/legacy.ts @@ -328,7 +328,7 @@ async function getProjectOwners( const ROUNDS_QUERY = ` query GetRounds( - $first: Int, + $first: Int, $orderBy: String, $orderDirection: String, $where: Round_filter, @@ -390,8 +390,8 @@ export const getRounds = async ( }, { graphqlEndpoints }: { graphqlEndpoints: Record }, ): Promise => { - let rounds: RoundOverview[] = await Promise.all( - params.chainIds.flatMap(async (chainId) => { + let roundsPromise: Promise[] = params.chainIds.flatMap( + async (chainId) => { const round = await graphql_fetch( ROUNDS_QUERY, graphqlEndpoints[chainId], @@ -403,15 +403,28 @@ export const getRounds = async ( chainId, })) ?? [] ); - }), + }, ); - rounds = rounds.flat(); + + let spamRounds: SpamRoundsMaps = {}; + try { + spamRounds = await fetchSpamRounds(); + } catch (e) { + console.error("Failed to fetch spam rounds", e); + } + + let rounds = (await Promise.all(roundsPromise)).flat(); rounds = cleanRoundData(rounds); rounds = sortRounds(rounds, params); + rounds = rounds.filter((round) => { + const isSpam = spamRounds[round.chainId]?.[round.id.toLowerCase()] === true; + return !isSpam; + }); + return rounds; }; -/* +/* Some timestamps are in milliseconds and others in overflowed values (115792089237316195423570985008687907853269984665640564039457584007913129639935) See this query: https://api.thegraph.com/subgraphs/name/gitcoinco/grants-round-optimism-mainnet/graphql?query=query+%7B%0A+++rounds%28first%3A+3%2C%0A++++++orderBy%3A+roundEndTime%2C%0A++++++orderDirection%3A+asc%0A++++%29+%7B%0A++++++id%0A++++++roundEndTime%0A+++++%0A++++%7D%0A%7D */ @@ -482,3 +495,39 @@ export const sortRounds = ( compareFn(a, b) ? dir[orderDirection] : -dir[orderDirection], ); }; + +type SpamRoundsMaps = { + [chainId: number]: { + [roundId: string]: boolean; + }; +}; + +// Temporary round curation to avoid spam +async function fetchSpamRounds(): Promise { + const spam: SpamRoundsMaps = {}; + + const csvContent = await fetch( + "https://docs.google.com/spreadsheets/d/10jekVhMuFg6IQ0sYAN_dxh_U-OxU7EAuGMNvTtlpraM/export?format=tsv", + ).then((res) => res.text()); + + const rows = csvContent.split("\n"); + rows + // skip the header row + .slice(1) + .forEach((line) => { + const columns = line.split("\t"); + const url = columns[1]; + // extract chainId and roundId + const regex = + /https:\/\/explorer\.gitcoin\.co\/#\/round\/(\d+)\/([0-9a-fA-Fx]+)/; + const match = url.match(regex); + if (match) { + const chainId = parseInt(match[1]); + const roundId = match[2].toLowerCase(); + spam[chainId] ||= {}; + spam[chainId][roundId] = true; + } + }); + + return spam; +}