import config from "@/utils/config.json"; import { _favoritedPlaces } from "@/utils/storage"; import { expireCache } from "@/utils/utilities"; import * as apiTypes from "@/utils/api/types"; import { getAPI } from "@/utils/api"; const placeID = window.location.pathname.split("/")[2]; /** * Displays a row of user-selected places at the top of the user's dashboard. */ export async function favoritedPlaces() { let placeIDs = await _favoritedPlaces.getValue(); const button = document.createElement("button"); button.classList.add("btn", "btn-primary", "btn-sm"); button.style.position = "absolute"; button.style.top = "0"; button.style.right = "0"; button.style.margin = "4px"; button.style.fontSize = "1.3em"; button.innerHTML = ` `; const update = function () { button.classList.value = "btn btn-primary btn-sm"; button.disabled = false; if (placeIDs.indexOf(placeID) == -1) { // Not Pinned if (placeIDs.length >= config.limits.favoritedPlaces) { button.disabled = true; } button.children[0].classList.value = "fa-regular fa-star"; } else { // Pinned button.children[0].classList.value = "fa-duotone fa-star"; } }; button.addEventListener("mouseenter", function () { if (placeIDs.indexOf(placeID) != -1) { button.classList.add("btn-danger"); button.classList.remove("btn-primary"); button.children[0].classList.add("fa-star-half-stroke"); button.children[0].classList.remove("fa-star"); } }); button.addEventListener("mouseleave", function () { if (placeIDs.indexOf(placeID) != -1) { button.classList.add("btn-primary"); button.classList.remove("btn-danger"); button.children[0].classList.add("fa-star"); button.children[0].classList.remove("fa-star-half-stroke"); } }); update(); document.querySelector("h1.my-0")!.parentElement!.appendChild(button); button.addEventListener("click", function () { if (placeIDs.indexOf(placeID) == -1) { placeIDs.push(placeID); } else { placeIDs.splice(placeIDs.indexOf(placeID), 1); } expireCache("favoritedPlaces"); _favoritedPlaces.setValue(placeIDs); update(); }); storage.watch>("sync:favoritedPlaces", (value, previous) => { placeIDs = value!; }); } /** * 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) */ export async function approxPlaceRevenue() { const publicAPI = getAPI("public"); const round = (number: number) => Math.round(number / config.economy.visitsPerBrick) * config.economy.visitsPerBrick; const infoCard = document.querySelector(".card-body .row:has(.fa-calendar)")!; const key = document.createElement("li"); const value = document.createElement("li"); key.innerHTML = "Revenue:"; value.innerHTML = "..."; value.classList.add(publicAPI.enabled ? "text-success" : "text-muted"); infoCard.children[0].appendChild(key); infoCard.children[1].appendChild(value); const revenue = await pullKVCache( "placeRevenue", placeID, async () => { if (!publicAPI.enabled) return "disabled"; const place: apiTypes.placeApiSchema = await (await fetch(publicAPI.url + "places/" + placeID)) .json(); const store: apiTypes.gamepassesApiSchema = await (await fetch( publicAPI.url + "places/" + placeID + "/gamepasses", )).json(); const creator: apiTypes.userApiSchema = await (await fetch( publicAPI.url + "users/" + place.creator.id, )).json(); const visitorPayout = round(place.uniqueVisits) / config.economy.visitsPerBrick; let gamepassRevenue = 0; for (const gamepass of store.gamepasses) { const price = Math.floor( gamepass.asset.price - (gamepass.asset.price * config.economy.membershipTax[creator.membershipType]), ); gamepassRevenue += price * gamepass.asset.sales; } return visitorPayout + gamepassRevenue; }, 300000, false, ); if (revenue == "disabled") { value.innerText = "Sorry, this feature is currently unavailable! Check back later!"; throw new Error( "[Poly+] API is disabled, cancelling approx. place revenue loading..", ); } value.innerHTML = ' ~' + revenue.toLocaleString(); }