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