Skip to content

Commit b03eb5a

Browse files
authored
Merge pull request #1743 from kleros/fix/evidence-sensor
feat(web): evidence moderation
2 parents 665a091 + 519a555 commit b03eb5a

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

web/.env.devnet.public

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export REACT_APP_GENESIS_BLOCK_ARBSEPOLIA=3084598
77
export REACT_APP_ATLAS_URI=http://localhost:3000
88
export REACT_APP_DEVTOOLS_URL=https://dev--kleros-v2-testnet-devtools.netlify.app
99
export NODE_OPTIONS='--max-old-space-size=7680'
10+
export REACT_APP_SPAM_EVIDENCES_IDS="0-2,3-1"
1011
# devtools
1112
export REACT_APP_GRAPH_API_KEY=

web/src/consts/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ export const genesisBlock = () => (isProductionDeployment() ? GENESIS_BLOCK_ARBM
4242

4343
export const INVALID_DISPUTE_DATA_ERROR = `The dispute data is not valid, please vote "Refuse to arbitrate"`;
4444
export const RPC_ERROR = `RPC Error: Unable to fetch dispute data. Please avoid voting.`;
45+
46+
export const spamEvidencesIds: string[] = (import.meta.env.REACT_APP_SPAM_EVIDENCES_IDS ?? "").split(",");

web/src/pages/Cases/CaseDetails/Evidence/index.tsx

+42-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useRef, useState } from "react";
1+
import React, { useCallback, useMemo, useRef, useState } from "react";
22
import styled from "styled-components";
33

44
import { useParams } from "react-router-dom";
@@ -17,6 +17,8 @@ import EvidenceCard from "components/EvidenceCard";
1717
import { SkeletonEvidenceCard } from "components/StyledSkeleton";
1818

1919
import EvidenceSearch from "./EvidenceSearch";
20+
import { Divider } from "components/Divider";
21+
import { spamEvidencesIds } from "src/consts";
2022

2123
const Container = styled.div`
2224
width: 100%;
@@ -54,12 +56,19 @@ const ScrollButton = styled(Button)`
5456
}
5557
`;
5658

59+
const SpamLabel = styled.label`
60+
color: ${({ theme }) => theme.primaryBlue};
61+
align-self: center;
62+
cursor: pointer;
63+
`;
64+
5765
const Evidence: React.FC = () => {
5866
const { id } = useParams();
5967
const { data: disputeData } = useDisputeDetailsQuery(id);
6068
const ref = useRef<HTMLDivElement>(null);
6169
const [search, setSearch] = useState<string>();
6270
const [debouncedSearch, setDebouncedSearch] = useState<string>();
71+
const [showSpam, setShowSpam] = useState(false);
6372

6473
const { data } = useEvidences(disputeData?.dispute?.externalDisputeId?.toString(), debouncedSearch);
6574

@@ -74,12 +83,19 @@ const Evidence: React.FC = () => {
7483
latestEvidence.scrollIntoView({ behavior: "smooth" });
7584
}, [ref]);
7685

86+
const evidences = useMemo(() => {
87+
if (!data?.evidences) return;
88+
const spamEvidences = data.evidences.filter((evidence) => isSpam(evidence.id));
89+
const realEvidences = data.evidences.filter((evidence) => !isSpam(evidence.id));
90+
return { realEvidences, spamEvidences };
91+
}, [data]);
92+
7793
return (
7894
<Container ref={ref}>
7995
<EvidenceSearch {...{ search, setSearch, evidenceGroup: disputeData?.dispute?.externalDisputeId }} />
8096
<ScrollButton small Icon={DownArrow} text="Scroll to latest" onClick={scrollToLatest} />
81-
{data ? (
82-
data.evidences.map(({ evidence, sender, timestamp, name, description, fileURI, evidenceIndex }) => (
97+
{evidences?.realEvidences ? (
98+
evidences?.realEvidences.map(({ evidence, sender, timestamp, name, description, fileURI, evidenceIndex }) => (
8399
<EvidenceCard
84100
key={timestamp}
85101
index={parseInt(evidenceIndex)}
@@ -90,9 +106,32 @@ const Evidence: React.FC = () => {
90106
) : (
91107
<SkeletonEvidenceCard />
92108
)}
109+
{evidences?.spamEvidences.length !== 0 ? (
110+
<>
111+
<Divider />
112+
{showSpam ? (
113+
evidences?.spamEvidences.map(
114+
({ evidence, sender, timestamp, name, description, fileURI, evidenceIndex }) => (
115+
<EvidenceCard
116+
key={timestamp}
117+
index={parseInt(evidenceIndex)}
118+
sender={sender?.id}
119+
{...{ evidence, timestamp, name, description, fileURI }}
120+
/>
121+
)
122+
)
123+
) : (
124+
<SpamLabel onClick={() => setShowSpam(true)}>Show likely spam</SpamLabel>
125+
)}
126+
</>
127+
) : null}
93128
{data && data.evidences.length === 0 ? <StyledLabel>There is no evidence submitted yet</StyledLabel> : null}
94129
</Container>
95130
);
96131
};
97132

133+
const isSpam = (id: string) => {
134+
return spamEvidencesIds.includes(id);
135+
};
136+
98137
export default Evidence;

0 commit comments

Comments
 (0)