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 { pullCache, bricksToCurrency } from "@/utils/utilities";
2import * as api from "@/utils/api";
3
4export function irlBrickPrice() {
5 const grid = document.getElementById('assets')!;
6
7 const addPrice = (item: HTMLElement) => {
8 const brickCount = item.getElementsByClassName('text-success')[0].textContent!;
9 const currency = bricksToCurrency(parseInt(brickCount), "USD");
10
11 if (currency) {
12 const spanTag = document.createElement('span');
13 spanTag.classList.add('text-muted');
14 spanTag.style.fontSize = '0.7rem';
15 spanTag.style.fontWeight = 'lighter';
16 spanTag.innerText = ` (${currency})`;
17 item.getElementsByClassName('text-success')[0].appendChild(spanTag);
18 };
19 };
20
21 for (const item of document.getElementsByClassName('itemCardCont')) {
22 addPrice(item as HTMLElement);
23 };
24
25 const mutations = new MutationObserver((mutations) => {
26 for (const record of mutations) {
27 for (const node of record.addedNodes) {
28 const item = node as HTMLElement;
29 if ((item as HTMLElement).classList.contains('itemCardCont')) addPrice(item);
30 };
31 };
32 });
33
34 mutations.observe(grid, { childList: true });
35};
36
37export async function ownedTags(userId: number) {
38 const grid = document.getElementById('assets')!;
39 const inventory = await pullCache(
40 'inventory',
41 async () => await api.iterate(
42 'public',
43 'users/' + userId + '/inventory?page=',
44 {
45 data: "inventory",
46 metadata: "meta"
47 },
48 1,
49 5
50 ),
51 300000,
52 false
53 );
54
55 const owns = (item: HTMLElement) => {
56 const itemId = parseInt(item.getAttribute('href')!.split('/')[2]);
57
58 if (inventory.find((item: {
59 asset: {
60 id: number
61 }
62 }) => item.asset.id == itemId)) {
63 return true;
64 };
65
66 return false;
67 };
68
69 const addTag = (item: HTMLElement) => {
70 const tag = document.createElement('span');
71 tag.classList.add('badge', 'bg-primary');
72 tag.setAttribute('style', `
73 position: absolute;
74 font-size: 0.9rem;
75 top: 0px;
76 left: 0px;
77 padding: 5.5px;
78 border-top-left-radius: var(--bs-border-radius-lg) !important;
79 border-top-right-radius: 0px;
80 border-bottom-left-radius: 0px;
81 font-size: 0.65rem;
82 `);
83 tag.innerHTML = "<i class='fas fa-star'></i>";
84
85 const image = item.getElementsByTagName('img')[0]!;
86 image.parentElement!.appendChild(tag);
87 };
88
89 for (const item of document.getElementsByClassName('itemCardCont')) {
90 const link: HTMLElement = item.getElementsByTagName('a')[0]!;
91 if (owns(link)) {
92 addTag(item as HTMLElement);
93 };
94 };
95
96 const mutations = new MutationObserver((mutations) => {
97 for (const record of mutations) {
98 for (const node of record.addedNodes) {
99 const item = node as HTMLElement;
100 if ((item as HTMLElement).classList.contains('itemCardCont')) {
101 const link: HTMLElement = item.getElementsByTagName('a')[0]!;
102 if (owns(link)) {
103 addTag(item as HTMLElement);
104 };
105 }
106 };
107 };
108 });
109
110 mutations.observe(grid, { childList: true });
111}