idle_moloch/app/src/components/Counter.tsx
2024-10-31 23:49:01 +01:00

83 lines
3.6 KiB
TypeScript

import { useEffect, useReducer, useRef } from "react";
import { usePlayer } from "../providers/PlayerProvider"
import styles from "../styles/Header.module.css"
import { formatUnits } from "viem";
export const calculateBalance = (balance: bigint, perSecond: bigint, lastRaidedAt: bigint) => {
// convert to milliseconds trick so we get a more smooth counter
const millisecondsSinceLastRaid =
(new Date()).getTime() - parseInt(lastRaidedAt.toString()) * 1000;
return (
balance +
(BigInt(millisecondsSinceLastRaid) * perSecond
/ BigInt(1000) /* deduct milliseconds*/))
}
export const toReadable = (rawValue: bigint) => {
const value = rawValue / BigInt(10000);
const suffixes = [
{ value: BigInt('1000'), suffix: 'k' }, // Thousand
{ value: BigInt('1000000'), suffix: 'M' }, // Million
{ value: BigInt('1000000000'), suffix: 'B' }, // Billion
{ value: BigInt('1000000000000'), suffix: 'T' }, // Trillion
{ value: BigInt('1000000000000000'), suffix: 'Qd' }, // Quadrillion
{ value: BigInt('1000000000000000000'), suffix: 'Qi' }, // Quintillion
{ value: BigInt('1000000000000000000000'), suffix: 'Sx' }, // Sextillion
{ value: BigInt('1000000000000000000000000'), suffix: 'Sp' }, // Septillion
{ value: BigInt('1000000000000000000000000000'), suffix: 'Oc' }, // Octillion
{ value: BigInt('1000000000000000000000000000000'), suffix: 'No' }, // Nonillion
{ value: BigInt('1000000000000000000000000000000000'), suffix: 'Dc' }, // Decillion
{ value: BigInt('1000000000000000000000000000000000000'), suffix: 'Ud' }, // Undecillion
{ value: BigInt('1000000000000000000000000000000000000000'), suffix: 'Dd' }, // Duodecillion
{ value: BigInt('1000000000000000000000000000000000000000000'), suffix: 'Td' }, // Tredecillion
{ value: BigInt('1000000000000000000000000000000000000000000000'), suffix: 'Qt' }, // Quattuordecillion
{ value: BigInt('1000000000000000000000000000000000000000000000000'), suffix: 'Qn' }, // Quindecillion
{ value: BigInt('1000000000000000000000000000000000000000000000000000'), suffix: 'Sd' }, // Sexdecillion
{ value: BigInt('1000000000000000000000000000000000000000000000000000000'), suffix: 'St' }, // Septendecillion
];
for (let i = 0; i < suffixes.length; i++) {
if (value < suffixes[i].value) {
if (i == 0) {
return formatUnits(rawValue, 4);
} else {
const divided = value / suffixes[i - 1].value;
const numStr = (value % suffixes[i - 1].value).toString().slice(0, 3);
const remainder = numStr == "0" ? "" : "." + parseInt(numStr.replace(/0+$/, ''), 10);
return `${divided.toString()}${remainder.toString()} ${suffixes[i - 1].suffix}`;
}
}
}
return value.toString();
}
const Counter = () => {
const { balance, army, player } = usePlayer();
const [, render] = useReducer(p => !p, false);
const balanceCount = useRef(balance ? balance.toString() : "0")
const availableBalance = useRef(balance ? balance.toString() : "0")
useEffect(() => {
const tickInterval = setInterval(() => {
balanceCount.current = toReadable(calculateBalance(
balance,
army?.profit_per_second ?? BigInt(0),
player?.last_raided_at ?? BigInt(0)
));
availableBalance.current = toReadable(balance);
render();
}, 100);
return () => clearInterval(tickInterval)
}, [balance, army?.profit_per_second, player?.last_raided_at])
return <>
<p className={styles.counter}>
{balanceCount.current} GELD
</p>
<p className={styles.counter_available}>in wallet: {availableBalance.current} GELD</p>
</>
}
export default Counter