Skip to content

Commit db29a3d

Browse files
committed
feat: myprofile links, subgraph changes, pagination, query optimization, levels miniguides tweak etc
1 parent af51757 commit db29a3d

File tree

25 files changed

+362
-183
lines changed

25 files changed

+362
-183
lines changed

subgraph/core/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ type Counter @entity {
237237
casesVoting: BigInt!
238238
casesRuled: BigInt!
239239
casesAppealing: BigInt!
240+
totalLeaderboardJurors: BigInt!
240241
}
241242

242243
type FeeToken @entity {

subgraph/core/src/KlerosCore.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ import { createCourtFromEvent } from "./entities/Court";
1818
import { createDisputeKitFromEvent, filterSupportedDisputeKits } from "./entities/DisputeKit";
1919
import { createDisputeFromEvent } from "./entities/Dispute";
2020
import { createRoundFromRoundInfo, updateRoundTimeline } from "./entities/Round";
21-
import { updateCases, updateCasesAppealing, updateCasesRuled, updateCasesVoting } from "./datapoint";
21+
import {
22+
updateCases,
23+
updateCasesAppealing,
24+
updateCasesRuled,
25+
updateCasesVoting,
26+
updateTotalLeaderboardJurors,
27+
} from "./datapoint";
2228
import { addUserActiveDispute, computeCoherenceScore, ensureUser } from "./entities/User";
2329
import { updateJurorStake } from "./entities/JurorTokensPerCourt";
2430
import { createDrawFromEvent } from "./entities/Draw";
2531
import { updateTokenAndEthShiftFromEvent } from "./entities/TokenAndEthShift";
2632
import { updateArbitrableCases } from "./entities/Arbitrable";
27-
import { ClassicVote, Court, Dispute, Draw, Round, User } from "../generated/schema";
33+
import { ClassicVote, Counter, Court, Dispute, Draw, Round, User } from "../generated/schema";
2834
import { BigInt } from "@graphprotocol/graph-ts";
2935
import { updatePenalty } from "./entities/Penalty";
3036
import { ensureFeeToken } from "./entities/FeeToken";
@@ -142,6 +148,11 @@ export function handleNewPeriod(event: NewPeriod): void {
142148
const juror = ensureUser(draw.juror);
143149
juror.totalResolvedVotes = juror.totalResolvedVotes.plus(ONE);
144150

151+
// Increment totalLeaderboardJurors in the Counter entity if this is the first resolved vote for the juror
152+
if (juror.totalResolvedVotes.equals(ONE)) {
153+
updateTotalLeaderboardJurors(ONE, event.block.timestamp);
154+
}
155+
145156
// Since this is a ClassicVote entity, this will only work for the Classic DisputeKit (which has ID "1").
146157
const vote = ClassicVote.load(`${round.disputeKit}-${draw.id}`);
147158

subgraph/core/src/datapoint.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const VARIABLES = [
1515
"casesVoting",
1616
"casesRuled",
1717
"casesAppealing",
18+
"totalLeaderboardJurors",
1819
];
1920

2021
function updateDataPoint(delta: BigInt, timestamp: BigInt, variable: string): void {
@@ -43,6 +44,7 @@ function checkFirstDayActivity(): void {
4344
counter.casesVoting = ZERO;
4445
counter.casesRuled = ZERO;
4546
counter.casesAppealing = ZERO;
47+
counter.totalLeaderboardJurors = ZERO;
4648
counter.save();
4749
}
4850
}
@@ -86,3 +88,7 @@ export function updateCasesRuled(delta: BigInt, timestamp: BigInt): void {
8688
export function updateCasesAppealing(delta: BigInt, timestamp: BigInt): void {
8789
updateDataPoint(delta, timestamp, "casesAppealing");
8890
}
91+
92+
export function updateTotalLeaderboardJurors(delta: BigInt, timestamp: BigInt): void {
93+
updateDataPoint(delta, timestamp, "totalLeaderboardJurors");
94+
}

web/src/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const App: React.FC = () => {
6565
}
6666
/>
6767
<Route
68-
path="jurors/*"
68+
path="jurors/:page/:order/:filter"
6969
element={
7070
<Suspense fallback={<Loader width={"48px"} height={"48px"} />}>
7171
<Jurors />

web/src/components/Popup/MiniGuides/JurorLevels.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ const leftPageContents = [
3535
title: "Juror Level 1: Pythagoras",
3636
paragraphs: [
3737
"Jurors are classified into distinct levels according to their performance starting from Level 1.",
38-
"Level 1: Jurors with 0 cases arbitrated, OR Jurors with ≥ 1 case arbitrated with 0-70% of coherent votes.",
38+
"Level 1: Jurors with ≥ 1 case arbitrated with 0-70% of coherent votes.",
3939
],
4040
},
4141
{
4242
title: "Juror Level 2: Socrates",
43-
paragraphs: ["Level 2: Jurors with ≥ 3 cases arbitrated with 70%-80% of coherent votes."],
43+
paragraphs: ["Level 2: Jurors with ≥ 3 cases arbitrated with more than 70% coherent votes."],
4444
},
4545
{
4646
title: "Juror Level 3: Plato",
47-
paragraphs: ["Level 3: Jurors with ≥ 7 cases arbitrated with 80%-90% of coherent votes."],
47+
paragraphs: ["Level 3: Jurors with ≥ 7 cases arbitrated with more than 80% of coherent votes."],
4848
},
4949
{
5050
title: "Juror Level 4: Aristotle",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useQuery } from "@tanstack/react-query";
2+
3+
import { useGraphqlBatcher } from "context/GraphqlBatcher";
4+
import { isUndefined } from "utils/index";
5+
6+
import { graphql } from "src/graphql";
7+
import { JurorsByCoherenceScoreQuery } from "src/graphql/graphql";
8+
export type { JurorsByCoherenceScoreQuery };
9+
10+
const jurorsByCoherenceScoreQuery = graphql(`
11+
query JurorsByCoherenceScore($skip: Int, $first: Int, $orderBy: User_orderBy, $orderDirection: OrderDirection) {
12+
users(
13+
first: $first
14+
skip: $skip
15+
orderBy: $orderBy
16+
orderDirection: $orderDirection
17+
where: { totalResolvedVotes_gt: 0 }
18+
) {
19+
id
20+
coherenceScore
21+
totalCoherentVotes
22+
totalResolvedVotes
23+
totalResolvedDisputes
24+
}
25+
}
26+
`);
27+
28+
export const useJurorsByCoherenceScore = (skip = 0, first = 20, orderBy: string, orderDirection: string) => {
29+
const isEnabled = !isUndefined(first);
30+
const { graphqlBatcher } = useGraphqlBatcher();
31+
32+
return useQuery<JurorsByCoherenceScoreQuery>({
33+
queryKey: [`JurorsByCoherenceScore`, skip, first, orderBy, orderDirection],
34+
enabled: isEnabled,
35+
staleTime: Infinity,
36+
queryFn: async () =>
37+
isEnabled
38+
? await graphqlBatcher.fetch({
39+
id: crypto.randomUUID(),
40+
document: jurorsByCoherenceScoreQuery,
41+
variables: {
42+
skip,
43+
first,
44+
orderBy,
45+
orderDirection,
46+
},
47+
})
48+
: undefined,
49+
});
50+
};

web/src/hooks/queries/useTopUsersByCoherenceScore.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useQuery } from "@tanstack/react-query";
2+
3+
import { useGraphqlBatcher } from "context/GraphqlBatcher";
4+
5+
import { graphql } from "src/graphql";
6+
import { TotalLeaderboardJurorsQuery } from "src/graphql/graphql";
7+
export type { TotalLeaderboardJurorsQuery };
8+
9+
const totalLeaderboardJurorsQuery = graphql(`
10+
query TotalLeaderboardJurors($id: ID!) {
11+
counter(id: $id) {
12+
totalLeaderboardJurors
13+
}
14+
}
15+
`);
16+
17+
export const useTotalLeaderboardJurors = () => {
18+
const { graphqlBatcher } = useGraphqlBatcher();
19+
20+
return useQuery<TotalLeaderboardJurorsQuery>({
21+
queryKey: [`TotalLeaderboardJurors`],
22+
staleTime: Infinity,
23+
queryFn: async () =>
24+
await graphqlBatcher.fetch({
25+
id: crypto.randomUUID(),
26+
document: totalLeaderboardJurorsQuery,
27+
variables: {
28+
id: 0,
29+
},
30+
}),
31+
});
32+
};

web/src/layout/Header/navbar/Explore.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const links = [
5454
{ to: "/", text: "Home" },
5555
{ to: "/cases/display/1/desc/all", text: "Cases" },
5656
{ to: "/courts", text: "Courts" },
57-
{ to: "/jurors", text: "Jurors" },
57+
{ to: "/jurors/1/desc/all", text: "Jurors" },
5858
{ to: "/get-pnk", text: "Get PNK" },
5959
];
6060

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from "react";
2+
import styled from "styled-components";
3+
4+
import ArrowIcon from "svgs/icons/arrow.svg";
5+
6+
import { AddressOrName, IdenticonOrAvatar } from "components/ConnectWallet/AccountDisplay";
7+
import { StyledArrowLink } from "components/StyledArrowLink";
8+
import { ISettings } from "../../../index";
9+
10+
const Container = styled.div`
11+
display: flex;
12+
justify-content: center;
13+
align-items: center;
14+
padding: 16px 32px;
15+
gap: 24px;
16+
border: 1px solid ${({ theme }) => theme.stroke};
17+
border-radius: 30px;
18+
19+
> label {
20+
color: ${({ theme }) => theme.primaryText};
21+
font-size: 16px;
22+
font-weight: 600;
23+
}
24+
`;
25+
26+
const AvatarAndAddressContainer = styled.div`
27+
display: flex;
28+
flex-direction: row;
29+
gap: 8px;
30+
`;
31+
32+
const ReStyledArrowLink = styled(StyledArrowLink)`
33+
font-size: 14px;
34+
35+
> svg {
36+
height: 14px;
37+
width: 14px;
38+
}
39+
`;
40+
41+
const WalletAndProfile: React.FC<ISettings> = ({ toggleIsSettingsOpen }) => {
42+
return (
43+
<Container>
44+
<AvatarAndAddressContainer>
45+
<IdenticonOrAvatar />
46+
<AddressOrName />
47+
</AvatarAndAddressContainer>
48+
<ReStyledArrowLink to={"/profile/1/desc/all"} onClick={toggleIsSettingsOpen}>
49+
My Profile <ArrowIcon />
50+
</ReStyledArrowLink>
51+
</Container>
52+
);
53+
};
54+
export default WalletAndProfile;

0 commit comments

Comments
 (0)