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

feat: oher currencies for irl -> brick price feature

Index 344bec7b 767b4102

.gitattributes
.gitignore
README.md
assets/chrome-icon.svg
assets/error.svg
assets/firefox-icon.svg
assets/plus.svg
assets/plusdx.svg
assets/typescript.svg
assets/vial.svg
components/counter.ts
entrypoints/account.content/friends.ts
entrypoints/account.content/index.ts
entrypoints/background.ts
entrypoints/devtools/index.html
entrypoints/devtools/main.ts
+2
entrypoints/forum.content/index.ts
···
if (window.location.pathname.includes("post")) {
// View
if (values.enabled.includes("forumMentions")) view.forumMentions();
+
+
view.generativeAI();
}
});
},
+28
entrypoints/forum.content/view.ts
···
+
import config from "@/utils/config.json";
+
/**
* Detects any username mentions in a forum post and turns them into clickable links.
*/
···
}
});
}
+
+
export function generativeAI() {
+
for (const userID of config.users.generativeAI) {
+
const cards = document.querySelectorAll(".card");
+
+
cards.forEach((card) => {
+
const user = card.querySelector(".forum-user-container");
+
+
if (user) {
+
const link = user.querySelector(`[href^="/users/${userID}"]`);
+
+
if (link) {
+
const textBlock = card.querySelector(".user-forum-content");
+
+
if (textBlock) {
+
const tag = document.createElement("span");
+
tag.classList.add("badge", "bg-secondary");
+
tag.innerText =
+
"This content may have been generated using AI. This information may not be factual.";
+
textBlock.appendChild(tag);
+
}
+
}
+
}
+
});
+
}
+
}
entrypoints/home.content.ts
entrypoints/places.content/index.ts
entrypoints/places.content/manage.ts
entrypoints/places.content/view.ts
entrypoints/popup/index.html
entrypoints/popup/style.css
entrypoints/preferences-handler.ts
entrypoints/preferences/index.html
entrypoints/profile.content/index.ts
entrypoints/profile.content/view.ts
+4 -1
entrypoints/sitewide.content.ts
···
preferences.getPreferences()
.then((values) => {
if (values.enabled.includes("irlBrickPrice")) {
-
const currency = bricksToCurrency(user.bricks, "USD");
+
const currency = bricksToCurrency(
+
user.bricks,
+
values.config.irlBrickPrice.currency,
+
);
if (currency) {
document.getElementsByClassName("brickBalanceCount")[0]
.textContent += ` (${currency})`;
entrypoints/store.content/discovery.ts
entrypoints/store.content/index.ts
entrypoints/store.content/view.ts
package.json
pnpm-lock.yaml
public/css/polytoria.css
public/css/preferences.css
public/icon/128.png
public/icon/16.png
public/icon/32.png
public/icon/48.png
public/icon/96.png
public/images/client-loading.png
public/images/greatdivide.png
public/images/icon-update.png
public/images/icon.png
public/images/preferences-splash1.png
public/images/preferences-splash2.png
+4 -3
public/preferences.json
···
"type": "select",
"subsetting": "currency",
"values": {
-
"USD": "United States Dollar (USD)"
+
"USD": "United States Dollar (USD)",
+
"EUR": "Euro (EUR)"
}
}
],
"notes": [
-
"!Currencies were calculated on [DATE].",
-
"!Currencies other than USD are purely approximations."
+
"!Currencies conversions were logged on May 26th, 2025 using a Google search because I'm lazy, sue me.",
+
"!All prices are purely estimations and will not be 100% accurate."
],
"tags": ["economy"]
},
public/svgs/chrome-icon.svg
public/svgs/error.svg
public/svgs/firefox-icon.svg
public/svgs/plus.svg
public/svgs/plusDx.svg
public/svgs/vial.svg
public/wxt.svg
tsconfig.json
utils/api/index.ts
utils/api/types.ts
+8 -8
utils/config.json
···
}
},
"limits": {
-
"favoritedPlaces": 15
+
"favoritedPlaces": 25
},
"economy": {
"membershipTax": {
-
"free": 0.35,
-
"plus": 0.25,
-
"plusDeluxe": 0.15
+
"free": 0.15,
+
"plus": 0.1,
+
"plusDeluxe": 0.05
},
-
"visitorPayouts": {
-
"visitors": 5,
-
"payout": 1
-
}
+
"visitsPerBrick": 5
+
},
+
"users": {
+
"generativeAI": [48196]
}
}
+6 -2
utils/currencyPackages.json
···
{
-
"USD": [
+
"base": [
[0.99, 100],
[4.99, 550],
[9.99, 1150],
[24.99, 2750],
[49.99, 6000],
[99.99, 12500]
-
]
+
],
+
"fromUSD": {
+
"EUR": 0.88
+
},
+
"updatedAt": "05-26-25"
}
+17 -5
utils/storage.ts
···
"accurateOwners",
],
config: {
+
irlBrickPrice: {
+
currency: "USD",
+
},
membershipThemes: {
themeId: "plus",
},
···
export const preferences: PreferencesStorageItem = storage.defineItem(
"sync:preferences",
-
{ fallback: defaultPreferences, version: 1 },
+
{
+
fallback: defaultPreferences,
+
version: 3,
+
migrations: {
+
3: () => defaultPreferences,
+
},
+
},
) as PreferencesStorageItem;
-
export const _favoritedPlaces = storage.defineItem("sync:favoritedPlaces", {
-
fallback: [],
-
version: 1,
-
});
+
export const _favoritedPlaces = storage.defineItem<string[]>(
+
"sync:favoritedPlaces",
+
{
+
fallback: [],
+
version: 1,
+
},
+
);
export const _bestFriends = storage.defineItem("sync:bestFriends", {
fallback: [],
utils/types.ts
+17 -12
utils/utilities.ts
···
): string | null {
if (isNaN(bricks) || bricks == 0) return null;
-
const _currencyPackages = currencyPackages as Record<
-
string,
-
Array<Array<number>>
-
>;
-
const packages = _currencyPackages[currency].toSorted((a, b) => b[1] - a[1]);
-
-
if (!packages) {
-
console.warn(
-
"[Poly+] Missing currency package data for selected currency!",
-
);
-
return null;
-
}
+
const _currencyPackages = currencyPackages as {
+
base: Array<number[]>;
+
fromUSD: Record<string, number>;
+
updatedAt: string;
+
};
+
const packages = _currencyPackages.base.toSorted((a, b) => b[1] - a[1]);
let totalValue = 0;
for (const [currencyValue, bricksValue] of packages) {
···
const [currencyValue, bricksValue] = cheapestPackage;
const unitPrice = currencyValue / bricksValue;
totalValue += bricks * unitPrice;
+
}
+
+
if (currency != "USD") {
+
if (!_currencyPackages.fromUSD[currency]) {
+
console.warn(
+
`[Poly+] Missing conversion from USD to ${currency}`,
+
);
+
return null;
+
}
+
+
totalValue *= _currencyPackages.fromUSD[currency];
}
return `~${totalValue.toFixed(2)} ${currency}`;
wxt.config.ts