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;
+}