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 config from "@/utils/config.json"; 2import { _favoritedPlaces } from "@/utils/storage"; 3import { expireCache } from "@/utils/utilities"; 4import * as apiTypes from "@/utils/api/types"; 5const placeID = window.location.pathname.split("/")[2]; 6 7/** 8 * Displays a row of user-selected places at the top of the user's dashboard. 9 */ 10export async function favoritedPlaces() { 11 let placeIDs = await _favoritedPlaces.getValue(); 12 13 const button = document.createElement("button"); 14 button.classList.add("btn", "btn-primary", "btn-sm"); 15 button.style.position = "absolute"; 16 button.style.top = "0"; 17 button.style.right = "0"; 18 button.style.margin = "4px"; 19 button.style.fontSize = "1.3em"; 20 button.innerHTML = ` 21 <i class="fa-regular fa-star"></i> 22 `; 23 24 const update = function () { 25 button.classList.value = "btn btn-primary btn-sm"; 26 button.disabled = false; 27 if (placeIDs.indexOf(placeID) == -1) { 28 // Not Pinned 29 if (placeIDs.length >= config.limits.favoritedPlaces) { 30 button.disabled = true; 31 } 32 button.children[0].classList.value = "fa-regular fa-star"; 33 } else { 34 // Pinned 35 button.children[0].classList.value = "fa-duotone fa-star"; 36 } 37 }; 38 39 button.addEventListener("mouseenter", function () { 40 if (placeIDs.indexOf(placeID) != -1) { 41 button.classList.add("btn-danger"); 42 button.classList.remove("btn-primary"); 43 button.children[0].classList.add("fa-star-half-stroke"); 44 button.children[0].classList.remove("fa-star"); 45 } 46 }); 47 48 button.addEventListener("mouseleave", function () { 49 if (placeIDs.indexOf(placeID) != -1) { 50 button.classList.add("btn-primary"); 51 button.classList.remove("btn-danger"); 52 button.children[0].classList.add("fa-star"); 53 button.children[0].classList.remove("fa-star-half-stroke"); 54 } 55 }); 56 57 update(); 58 document.querySelector("h1.my-0")!.parentElement!.appendChild(button); 59 60 button.addEventListener("click", function () { 61 if (placeIDs.indexOf(placeID) == -1) { 62 placeIDs.push(placeID); 63 } else { 64 placeIDs.splice(placeIDs.indexOf(placeID), 1); 65 } 66 67 expireCache("favoritedPlaces"); 68 _favoritedPlaces.setValue(placeIDs); 69 update(); 70 }); 71 72 storage.watch<Array<string>>("sync:favoritedPlaces", (value, previous) => { 73 placeIDs = value!; 74 }); 75} 76 77/** 78 * Displays the approximated amount of revenue generated from a certain place, based off the unique visits & any gamepass sales (taking into account the creator's current membership tax) 79 */ 80export async function approxPlaceRevenue() { 81 const round = (number: number) => 82 Math.round(number / config.economy.visitorPayouts.visitors) * 83 config.economy.visitorPayouts.visitors; 84 const infoCard = document.querySelector(".card-body .row:has(.fa-calendar)")!; 85 86 const key = document.createElement("li"); 87 const value = document.createElement("li"); 88 89 key.innerHTML = "Revenue:"; 90 value.innerHTML = "..."; 91 value.classList.add(config.api.enabled ? "text-success" : "text-muted"); 92 93 infoCard.children[0].appendChild(key); 94 infoCard.children[1].appendChild(value); 95 96 const revenue = await pullKVCache( 97 "placeRevenue", 98 placeID, 99 async () => { 100 if (!config.api.enabled) return "disabled"; 101 102 const place: apiTypes.placeApiSchema = 103 await (await fetch(config.api.urls.public + "places/" + placeID)) 104 .json(); 105 const store: apiTypes.gamepassesApiSchema = await (await fetch( 106 config.api.urls.public + "places/" + placeID + "/gamepasses", 107 )).json(); 108 const creator: apiTypes.userApiSchema = await (await fetch( 109 config.api.urls.public + "users/" + place.creator.id, 110 )).json(); 111 112 const visitorPayout = round(place.uniqueVisits) / 113 config.economy.visitorPayouts.visitors; 114 let gamepassRevenue = 0; 115 116 for (const gamepass of store.gamepasses) { 117 const price = Math.floor( 118 gamepass.asset.price - 119 (gamepass.asset.price * 120 config.economy.membershipTax[creator.membershipType]), 121 ); 122 gamepassRevenue += price * gamepass.asset.sales; 123 } 124 125 return visitorPayout + gamepassRevenue; 126 }, 127 300000, 128 false, 129 ); 130 131 if (revenue == "disabled") { 132 value.innerText = 133 "Sorry, this feature is currently unavailable! Check back later!"; 134 throw new Error( 135 "[Poly+] API is disabled, cancelling approx. place revenue loading..", 136 ); 137 } 138 139 value.innerHTML = '<i class="pi pi-brick me-2"></i> ~' + 140 revenue.toLocaleString(); 141}