mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
#1078 is at about 4,000 lines changed and includes both code implementing features and unrelated functional and stylistic changes. This set of changes is about ⅓ of the total and should be largely independent. These changes include: * have Dependabot ignore `patch` version changes * switch the cache invalidation Hasura action to asynchronous * add a uniqueness constraint on the combination of player and skill ids * print a comprehensible error message in the db seeding script on network errors * add a mutex on the account creation process & allow it to happen only once *(subsequent runs were failing b/c of the uniqueness constraint on the ETH address & returning `null` (closes #1098)) * adds some more profile editing related types * renames `HighLow7dType` to `HighLowType` * refactors the `ColorBar` component to include links to a color explanation * replaces `fake-tag`'s `gql` string identifier with the dependency-free `/* GraphQL */` * rename `lib/hooks/useUserXp.ts` to `useUserXP.ts` * fixed some typings to remove `any`s * bumped some library versions & fixed the version numbers of some others
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { Constants } from '@metafam/utils';
|
|
import { ethers } from 'ethers';
|
|
import { useEffect, useState } from 'react';
|
|
import { SCAccount, SCAccountsData } from 'sourcecred';
|
|
|
|
interface XPProps {
|
|
userTotalXP: number;
|
|
variationThisWeek: number;
|
|
variationLastWeek: number;
|
|
thisWeekXP: number;
|
|
lastWeekXP: number;
|
|
userWeeklyCred: number[];
|
|
}
|
|
|
|
export const useUserXP = (userAddress: string): XPProps | null => {
|
|
const [xpDataObj, setXPDataObj] = useState<XPProps | null>(null);
|
|
useEffect(() => {
|
|
if (ethers.utils.isAddress(userAddress))
|
|
getXP(userAddress).then((res) => {
|
|
if (res) setXPDataObj(res);
|
|
});
|
|
}, [userAddress]);
|
|
return xpDataObj;
|
|
};
|
|
|
|
const getXP = async (userAddress: string): Promise<XPProps | null> => {
|
|
try {
|
|
const accountsData: SCAccountsData = await (
|
|
await fetch(Constants.SC_ACCOUNTS_FILE)
|
|
).json();
|
|
|
|
const scAccount = await accountsData.accounts.find((account) =>
|
|
accountFilter(account, userAddress),
|
|
);
|
|
|
|
if (!scAccount) return null;
|
|
|
|
const userTotalXP = roundToTwoDecimal(scAccount.totalCred);
|
|
const numWeeks = scAccount.cred.length;
|
|
const userWeeklyCred = scAccount.cred;
|
|
|
|
let variationThisWeek = calculateVariation(
|
|
userWeeklyCred[numWeeks - 1],
|
|
userWeeklyCred[numWeeks - 2],
|
|
);
|
|
let variationLastWeek = calculateVariation(
|
|
userWeeklyCred[numWeeks - 2],
|
|
userWeeklyCred[numWeeks - 3],
|
|
);
|
|
|
|
const thisWeekXP = roundToTwoDecimal(userWeeklyCred[numWeeks - 1]);
|
|
const lastWeekXP = roundToTwoDecimal(userWeeklyCred[numWeeks - 2]);
|
|
variationThisWeek = roundToTwoDecimal(variationThisWeek);
|
|
variationLastWeek = roundToTwoDecimal(variationLastWeek);
|
|
|
|
return {
|
|
userTotalXP,
|
|
variationThisWeek,
|
|
variationLastWeek,
|
|
thisWeekXP,
|
|
lastWeekXP,
|
|
userWeeklyCred,
|
|
};
|
|
} catch (err: unknown) {
|
|
// throw new Error(err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const accountFilter = (a: SCAccount, userAddress: string) => {
|
|
const { account } = a;
|
|
|
|
const acc = account.identity.aliases.find(
|
|
(alias) => alias.description.toLowerCase() === userAddress.toLowerCase(),
|
|
);
|
|
return !!acc;
|
|
};
|
|
|
|
const calculateVariation = (first: number, second: number) =>
|
|
(100 * (first - second)) / second;
|
|
|
|
const roundToTwoDecimal = (num: number): number => Math.round(num * 100) / 100;
|