A rewrite of Poly+, my quality-of-life browser extension for Polytoria. Built entirely fresh using the WXT extension framework, Typescript, and with added better overall code quality.
extension
1import { cache } from "./storage";
2import { cacheInterface } from "./types";
3import * as currencyPackages from "./currencyPackages.json"
4
5export async function pullCache(key: string, replenish: Function, expiry: number, forceReplenish: boolean) {
6 const cacheStorage: cacheInterface = await cache.getValue();
7 const metadata = await cache.getMeta() as { [key: string]: number; };
8
9 if (!cacheStorage[key] || forceReplenish || (Date.now() - metadata[key] >= expiry)) {
10 console.info('[Poly+] "' + key + '" cache is stale replenishing...');
11
12 const replenishedCache = await replenish();
13 cacheStorage[key] = replenishedCache;
14 metadata[key] = Date.now();
15
16 cache.setValue(cacheStorage);
17 cache.setMeta(metadata);
18 }
19
20 return cacheStorage[key];
21};
22
23export async function expireCache(key: string) {
24 console.info('[Poly+] Forcefully expiring "' + key + '" cache...');
25
26 const metadata = await cache.getMeta() as { [key: string]: number };
27 metadata[key] = 0;
28 cache.setMeta(metadata);
29}
30
31export async function getUserDetails() {
32 const profileLink: HTMLLinkElement = document.querySelector('.navbar a.text-reset[href^="/users/"]')!;
33 const brickBalance = document.getElementsByClassName('brickBalanceCount')[0];
34
35 if (!profileLink || !brickBalance) return null;
36 return {
37 username: profileLink.innerText.trim(),
38 userId: parseInt(profileLink.href.split('/')[4]),
39 bricks: parseInt(brickBalance.textContent!.replace(/,/g, ""))
40 }
41};
42
43export function bricksToCurrency(bricks: number, currency: string): string | null {
44 if (isNaN(bricks) || bricks == 0) return null;
45
46 const _currencyPackages = currencyPackages as Record<string, Array<Array<number>>>;
47 const packages = _currencyPackages[currency].toSorted((a, b) => b[1] - a[1]);
48
49 if (!packages) {
50 console.warn('[Poly+] Missing currency package data for selected currency!');
51 return null;
52 }
53
54 let totalValue = 0;
55 for (const [currencyValue, bricksValue] of packages) {
56 while (bricks >= bricksValue) {
57 bricks -= bricksValue;
58 totalValue += currencyValue;
59 }
60 }
61
62 if (bricks > 0) {
63 const cheapestPackage = packages[packages.length - 1];
64 const [currencyValue, bricksValue] = cheapestPackage;
65 const unitPrice = currencyValue / bricksValue;
66 totalValue += bricks * unitPrice;
67 }
68
69 return `~${totalValue.toFixed(2)} ${currency}`;
70};