Updates and Bug Fixes

- Experimental Feature: Event Items Store Category

- Fixed "Try On" store items

- Deleted "Try On" store items code and moved it to the main item view page script

- Fixed Transactions page Bricks to IRL Price converter

- Transactions page bricks to IRL Price converter now doesn't say "$NaN" when the input is erased

- Deleted popup and installation HTML files as they aren't used and haven't been used for a while. I am thinking of adding a new popup when you click the extension icon in your browser toolbar but that will be different than the code that was there.

- New Feature: Show "Owners" instead of "Sales"

- Updated theme code to run on all pages, even when the "Theme Creator" feature is turned off so that CSS such as modal CSS can still apply without other scripts having to apply their own CSS blob to the page

- Updated context menu background code to remove all context menus created by the extension before creating the context menus so the error for duplicate context menu IDs won't keep appearing (hopefully, but I haven't gotten the error yet so...)

- Fixed "Trending Items" IRL Brick price breaking if any of the trending items are free

- Improved detection for the purchase button on item view pages

- Fixed the item view page not checking if the item isn't owned before trying to add the IRL Brick price

- Removed old setTimeout() code at the start of some files
This commit is contained in:
Index 2024-04-20 11:58:00 -05:00
parent 9478b85f49
commit eeaafeb35a
17 changed files with 618 additions and 475 deletions

View file

@ -1,8 +0,0 @@
<html>
<head>
<title>Poly+</title>
</head>
<body>
<p>Thank you for installing Poly+!</p>
</body>
</html>

View file

@ -1,7 +1,6 @@
var SelectedFriends = []
setTimeout(function () {
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
Settings = result.PolyPlus_Settings;
if (Settings.ImprovedFrListsOn === true) {
var Tab = "requests"
@ -208,5 +207,4 @@ setTimeout(function () {
})
}
}
});
}, 100);
});

View file

@ -6,6 +6,8 @@ var Settings;
var PinnedGamesData
var BestFriendsData
let Utilities;
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result) {
Settings = result.PolyPlus_Settings || {}
@ -170,19 +172,21 @@ SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]);
async function IRLPrice() {
(async () => {
let Utilities = await import(chrome.runtime.getURL('/js/resources/utils.js'));
Utilities = await import(chrome.runtime.getURL('/js/resources/utils.js'));
Utilities = Utilities.default
const TrendingItems = document.getElementById('home-trendingItems')
for (let item of TrendingItems.children[1].getElementsByClassName('d-flex')[0].children) {
const Price = item.getElementsByClassName('text-success')[0]
if (Price !== undefined) {
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrencyCurrency)
let Span = document.createElement('span')
Span.classList = 'text-muted polyplus-price-tag'
Span.style.fontSize = '0.7rem'
Span.style = 'font-size: 0.7rem; font-weight: lighter;'
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
Price.appendChild(Span)
}
}
})();
}

View file

@ -1,5 +1,3 @@
setTimeout(function () {}, 100)
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
if (result.PolyPlus_Settings.MoreSearchFiltersOn === true) {
const BlockedUsersCard = document.getElementsByClassName('card-body')[1]

View file

@ -1,4 +1,3 @@
setTimeout(function() {}, 100)
var SelectedTrades = []
let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement

View file

@ -1,5 +1,3 @@
setTimeout(function () {}, 100)
/*
let Currencies;
@ -15,7 +13,7 @@ let Utilities;
Utilities = Utilities.default
})();
let Nav = document.querySelector('.nav-pills')
let Nav = document.getElementsByClassName('nav-pills')[0]
let DIV = document.createElement('div')
DIV.innerHTML = `
<input id="polyplus-brickconverter-input" type="number" class="form-control bg-dark mb-2" placeholder="How many Bricks?">
@ -66,10 +64,11 @@ Package.addEventListener('change', function(){
*/
async function Update(){
//let DISPLAY = Type.options[Type.selectedIndex].value
//let IRL = (parseInt(Input.value.replace(/,/g, '')) * Currencies.Data[Package.selectedIndex][DISPLAY]).toFixed(2)
if (Input.value === "") {
Output.value = ''
return
}
const IRLResult = await Utilities.CalculateIRL(Input.value, Type.selectedIndex)
console.log(Input.value, Type.options[Type.selectedIndex].value, Result)
Output.value = "$" + IRLResult.result + " " + IRLResult.display
}

View file

@ -71,17 +71,19 @@ function RunUpdateNotifier() {
}
});
}
chrome.contextMenus.create({
chrome.contextMenus.removeAll(function() {
chrome.contextMenus.create({
title: 'Run Update Notifier',
id: 'PolyPlus-RunUpdateNotifier',
contexts: ['all'],
documentUrlPatterns: [
"https://polytoria.com/my/settings/polyplus-debug",
]
});
});
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
chrome.contextMenus.create({
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
chrome.contextMenus.create({
title: 'Copy Asset ID',
id: 'PolyPlus-CopyID',
contexts: ['link'],
@ -94,10 +96,10 @@ chrome.contextMenus.create({
"https://polytoria.com/users/**",
"https://polytoria.com/store/**"
]
});
});
// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION
chrome.contextMenus.create({
// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION
chrome.contextMenus.create({
title: 'Copy Avatar Hash',
id: 'PolyPlus-CopyAvatarHash',
contexts: ['image'],
@ -109,7 +111,8 @@ chrome.contextMenus.create({
"https://c0.ptacdn.com/thumbnails/avatars/**",
"https://c0.ptacdn.com/thumbnails/avatars/**"
]
});
});
})
// HANDLE CONTEXT MENU ITEMS
chrome.contextMenus.onClicked.addListener(function (info, tab){

View file

@ -223,5 +223,5 @@ document.getElementById('delete-all-data').addEventListener('click', function(){
});
chrome.storage.sync.getBytesInUse(["PolyPlus_Settings", "PolyPlus_PinnedGames", "PolyPlus_BestFriends", "PolyPlus_ItemWishlist"], function(bytes){
document.getElementById('data-size').innerText = bytes
document.getElementById('data-size').innerText = bytes.toLocaleString()
});

View file

@ -1,5 +1,13 @@
var Settings;
let Theme = null;
let Theme = `
html:has(.polyplus-modal[open]), body:has(.polyplus-modal[open]) {
overflow: hidden;
}
.polyplus-modal::backdrop {
background: rgba(0, 0, 0, 0.73);
}
`;
(async () => {
let Utilities = await import(chrome.runtime.getURL('/js/resources/utils.js'));
@ -24,7 +32,7 @@ let Theme = null;
Settings.ThemeCreator.BGImageSize = 'contain'
break
}
Theme = `
Theme += `
:root {
--polyplus-navbgcolor: ${Settings.ThemeCreator.NavBGColor};
--polyplus-navbordercolor: ${Settings.ThemeCreator.NavBorderColor};
@ -111,11 +119,11 @@ let Theme = null;
color: var(--polyplus-sidebaritemlabelcolor) !important;
}
`
}
const ThemeBlob = new Blob([Theme], { type: 'text/css' })
const ThemeURL = window.URL.createObjectURL(ThemeBlob)
document.head.innerHTML += `<link href="${ThemeURL}" rel="stylesheet" type="text/css">`
}
});
document.addEventListener('DOMContentLoaded', async function() {

View file

@ -400,13 +400,17 @@ async function IRLPrice() {
}
async function PlaceRevenue() {
const Visits = parseInt(document.querySelector('li:has(i.fad.fa-users.text-muted[style])').innerText)
const BricksPerView = 5
let Revenue = (round5(Visits) / 5)
let PlaceDetails = await fetch('https://api.polytoria.com/v1/places/' + PlaceID)
PlaceDetails = await PlaceDetails.json()
let CreatorDetails = await fetch('https://api.polytoria.com/v1/users/' + GameCreator)
CreatorDetails = await CreatorDetails.json()
let Total = (round5(PlaceDetails.uniqueVisits) / 5)
let Revenue = (round5(PlaceDetails.uniqueVisits) / 5)
let CreatorTax = 0.35
switch (CreatorDetails.membershipType) {
case 'plus':
@ -417,19 +421,23 @@ async function PlaceRevenue() {
break
}
fetch(`https://api.polytoria.com/v1/places/${PlaceID}/gamepasses`)
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
for (let gamepass of data.gamepasses) {
let Achievements = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/achievements')
Achievements = await Achievements.json()
let Gamepasses = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/gamepasses')
Gamepasses = await Gamepasses.json()
for (let gamepass of Gamepasses.gamepasses) {
const PriceAfterTax = Math.floor(gamepass.asset.price - (gamepass.asset.price * CreatorTax))
Revenue += (PriceAfterTax * gamepass.asset.sales)
}
/*
for (let achievement of Achievements.achievements) {
// decrease total by price of achievement creation based on when the achievement was created
}
*/
const ResultText = document.createElement('li')
ResultText.classList = 'fw-normal text-success'
ResultText.style.letterSpacing = '0px'
@ -437,10 +445,6 @@ async function PlaceRevenue() {
CalculateRevenueButton.remove()
InfoColumns[1].appendChild(ResultText)
})
.catch(error => {
console.log(error)
});
}
function round5(number) { const remainder = number % 5; if (remainder < 2.5) { return number - remainder; } else { return number + (5 - remainder); } }

View file

@ -63,7 +63,11 @@ export default {
ApplyMembershipThemeTheme: 0,
MultiCancelOutTradesOn: true,
ItemWishlistOn: true,
HideUpgradeBtnOn: false
HideUpgradeBtnOn: false,
TryOnItemsOn: true,
OutfitCostOn: true,
ShowPlaceRevenueOn: true,
ReplaceItemSalesOn: false
},
CalculateIRL: async function(bricks, to, brickPackage) {
/*
@ -81,7 +85,6 @@ export default {
let Display = "Currency Not Found";
bricks = ParseFullNumber(bricks.replace(/,/g, ''))
console.log(bricks)
switch (to) {
// U.S. Dollar
case 0:
@ -91,43 +94,43 @@ export default {
// Euro
case 1:
Result = (bricks.replace(/,/g, '') * 0.009).toFixed(2)
Result = (bricks * 0.009).toFixed(2)
Display = "EUR"
break
// Canadian Dollar
case 2:
Result = (bricks.replace(/,/g, '') * 0.0131).toFixed(2)
Result = (bricks * 0.0131).toFixed(2)
Display = "CAD"
break
// Great British Pound
case 3:
Result = (bricks.replace(/,/g, '') * 0.0077).toFixed(2)
Result = (bricks * 0.0077).toFixed(2)
Display = "GBP"
break
// Mexican Peso
case 4:
Result = (bricks.replace(/,/g, '') * 0.1691).toFixed(2)
Result = (bricks * 0.1691).toFixed(2)
Display = "MXN"
break
// Australia Dollar
case 5:
Result = (bricks.replace(/,/g, '') * 0.0144).toFixed(2)
Result = (bricks * 0.0144).toFixed(2)
Display = "AUD"
break
// Turkish Lira
case 6:
Result = (bricks.replace(/,/g, '') * 0.2338).toFixed(2)
Result = (bricks * 0.2338).toFixed(2)
Display = "TRY"
break
// Brazillian Real
case 7:
Result = (bricks.replace(/,/g, '') * 0.49).toFixed(2)
Result = (bricks * 0.49).toFixed(2)
Display = "BRL"
break
}

View file

@ -1,5 +1,16 @@
const ItemID = window.location.pathname.split('/')[2]
const ItemType = document.querySelector('.col-12 .badge').innerHTML
const MeshTypes = [
"hat",
"hair",
"head attachment",
"face accessory",
"neck accessory",
"head cover",
"back accessory",
"shoulder accessory",
"tool"
]
var Utilities;
@ -15,19 +26,42 @@ var ItemOwned;
Utilities = await import(chrome.runtime.getURL('/js/resources/utils.js'));
Utilities = Utilities.default
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){
Settings = result.PolyPlus_Settings || {}
PurchaseBtn = document.querySelector('.btn#purchase-button')
if (ItemType === "gamePass") {
PurchaseBtn = document.querySelector('.btn.btn-outline-success[onclick^="buyAsset"]')
}
ItemOwned = (PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null)
if (Settings.IRLPriceWithCurrencyOn === true) { IRLPrice() }
PurchaseBtn = document.querySelector('.btn[onclick^="buyAsset"]')
if (PurchaseBtn === null) {
PurchaseBtn = document.querySelector('.btn#purchase-button')
}
/*
if (ItemType === "gamePass") {
PurchaseBtn = document.querySelector('[onclick^="buyAsset"]')
}
*/
ItemOwned = (PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null)
console.log(PurchaseBtn, ItemOwned)
if (Settings.IRLPriceWithCurrencyOn === true && ItemOwned === false) {
IRLPrice()
}
if (Settings.ItemWishlistOn === true) {
HandleItemWishlist()
}
if (Settings.TryOnItemsOn === true) {
TryOnItems()
}
if (Settings.ReplaceItemSalesOn === true) {
const Sales = document.querySelectorAll('.col:has(h6):has(h3.small)')[2]
if (Sales.children[1].innerText === '0') {
const Owners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=1')).json()).total
Sales.children[0].innerText = 'Owners'
Sales.children[1].innerText = Owners.toLocaleString()
}
}
})
})();
@ -61,7 +95,6 @@ chrome.storage.onChanged.addListener(function(changes, namespace) {
});
async function IRLPrice() {
if (!(PurchaseBtn.getAttribute('disabled'))) {
const Price = PurchaseBtn.getAttribute('data-price')
const Span = document.createElement('span')
Span.classList = 'text-muted polyplus-own-tag'
@ -70,7 +103,6 @@ async function IRLPrice() {
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrencyCurrency)
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
PurchaseBtn.appendChild(Span)
}
}
function HandleItemWishlist() {
@ -137,3 +169,144 @@ function HandleItemWishlist() {
DescriptionText.appendChild(WishlistBtn)
});
}
function TryOnItems() {
const Avatar = {
"useCharacter": true,
"items": [],
"shirt": "https://c0.ptacdn.com/assets/uWrrnFGwgNN5W171vqYTWY7E639rKiXK.png",
"pants": "https://c0.ptacdn.com/assets/HD6TFdXD8CaflRNmd84VCNyNsmTB0SH3.png",
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
let AssetType = document.querySelector('.px-4.px-lg-0.text-muted.text-uppercase.mb-3 .badge').innerHTML
console.log(AssetType, MeshTypes[AssetType], MeshTypes[AssetType.toLowerCase()])
/*
if (HatTypes[AssetType.toLowerCase()] !== undefined) {
AssetType = "hat"
}
*/
const ItemThumbnail = document.getElementsByClassName('store-thumbnail')[0]
const IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
const TryIFrame = document.createElement('iframe')
TryIFrame.style = 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px;'
const TryOnBtn = document.createElement('button')
TryOnBtn.classList = 'btn btn-outline-warning'
TryOnBtn.style = 'position: absolute; bottom: 60px; right: 10px;'
TryOnBtn.innerHTML = '<i class="fa-duotone fa-vial"></i>'
TryOnBtn.addEventListener('click', function (){
TryOnModal.showModal()
});
let TryOnModal = document.createElement('dialog')
TryOnModal.classList = 'polyplus-modal'
TryOnModal.setAttribute('style', 'width: 450px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;')
TryOnModal.innerHTML = `
<div class="text-muted mb-2" style="font-size: 0.8rem;">
<h5 class="mb-0" style="color: #fff;">Preview</h5>
Try on this item!
</div>
<div class="modal-body">
<button class="btn btn-primary w-100 mx-auto" onclick="this.parentElement.parentElement.close();">Close</button>
</div>
`
document.body.prepend(TryOnModal)
ItemThumbnail.parentElement.appendChild(TryOnBtn)
TryOnModal.children[1].prepend(TryIFrame)
fetch("https://api.polytoria.com/v1/users/:id/avatar".replace(':id', JSON.parse(window.localStorage.getItem('account_info')).ID))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
data.assets.forEach(item => {
switch (item.type) {
case 'hat':
Avatar.items[Avatar.items.length] = item.path || ''
break
case 'face':
Avatar.face = item.path || ''
break
case 'tool':
Avatar.tool = item.path || ''
break
case 'shirt':
Avatar.shirt = item.path || ''
break
case 'pants':
Avatar.pants = item.path || ''
break
}
});
Avatar.headColor = "#" + data.colors.head
Avatar.torsoColor = "#" + data.colors.torso
Avatar.leftArmColor = "#" + data.colors.leftArm
Avatar.rightArmColor = "#" + data.colors.rightArm
Avatar.leftLegColor = "#" + data.colors.leftLeg
Avatar.rightLegColor = "#" + data.colors.rightLeg
if (MeshTypes.indexOf(AssetType.toLowerCase()) !== -1) {
fetch("https://api.polytoria.com/v1/assets/serve-mesh/:id".replace(':id', window.location.pathname.split('/')[2]))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
if (AssetType === 'hat') {
Avatar.items[Avatar.items.length] = data.url
} else if (AssetType === 'tool') {
Avatar.tool = data.url
}
console.log(Avatar)
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
})
.catch(error => {
console.error('Fetch error:', error);
});
} else {
fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', window.location.pathname.split('/')[2]))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
switch (AssetType) {
case 'shirt':
Avatar.shirt = data.url
break
case 'pants':
Avatar.pants = data.url
break
case 'face':
Avatar.face = data.url
break
}
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
})
.catch(error => {
console.error('Fetch error:', error);
});
}
})
.catch(error => {
console.error('Fetch error:', error);
});
}

View file

@ -1,7 +1,9 @@
const ItemID = window.location.pathname.split('/')[2]
const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
const ItemGrid = document.getElementById('assets')
var Settings;
var Inventory = null;
var Utilities;
(async () => {
Utilities = await import(chrome.runtime.getURL('/js/resources/utils.js'));
@ -10,8 +12,6 @@ var Utilities;
Update()
})();
const ItemGrid = document.getElementById('assets')
var Inventory = null;
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ Settings = result.PolyPlus_Settings || Utilities.DefaultSettings; });
@ -29,6 +29,9 @@ async function Update() {
});
}
if (Settings.EventItemsCatOn === true) {
EventItems()
}
}
const observer = new MutationObserver(async function (list){
@ -84,3 +87,92 @@ function CheckInventory(id) {
})
return Item
}
function EventItems() {
const Categories = document.getElementById('store-categories').children[0]
const Selector = document.createElement('div')
Selector.classList = 'form-check store-category-check fw-bold'
Selector.style.borderColor = '#B008B0'
Selector.innerHTML = `
<input class="form-check-input" type="radio" name="storecat" id="storecat-eventitems">
<label class="form-check-label" for="storecat-eventitems">
<i class="fad fa-party-horn"></i> Event Items
</label>
`
Categories.appendChild(Selector)
const CategoryDiv = document.createElement('div')
ItemGrid.parentElement.insertBefore(CategoryDiv, ItemGrid)
let EventData = null
let Events = []
let Groups = []
Array.from(Categories.children).forEach(selector => {
if (selector !== Selector) {
selector.children[0].addEventListener('click', function() {
ItemGrid.innerHTML = ``
ItemGrid.classList.add('itemgrid')
})
}
})
Selector.children[0].addEventListener('click', async function() {
EventItemsEnabled = true
Array.from(Categories.children).forEach(selector => {
selector.classList.remove('active')
})
Selector.classList.add('active')
if (EventData === null) {
EventData = await (await fetch('https://polyplus.vercel.app/data/eventItems.json')).json()
Object.values(EventData.eventDetails).forEach((x, index) => {Groups.push({
...x,
items: EventData.items.filter((x) => x.event === Object.keys(EventData.eventDetails)[index])
})})
while (Events.length > 0) {
Groups.push(Events.splice(0, 3))
}
}
console.log(Groups)
ItemGrid.classList.remove('itemgrid')
ItemGrid.innerHTML = `
${
Groups.map((x, index) => `
<div class="row px-2 px-lg-0" style="animation-delay: 0.24s;">
<div class="col">
<h6 class="dash-ctitle2">${x.date}</h6>
<h5 class="dash-ctitle">${x.name}</h5>
</div>
</div>
<div class="card card-dash mcard mb-3" style="animation-delay: 0.27s;">
<div class="card-body p-0 m-1 scrollFadeContainer">
<div class="d-flex">
${
x.items.map((x) => `
<a href="/store/${x.id}">
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
<div class="card-body">
<img src="${x.thumbnail}" class="place-card-image">
<div>
<div class="mt-2 mb-1 place-card-title">
${x.name}
</div>
</div>
</div>
</div>
</a>
`).join('')
}
</div>
</div>
</div>
</div>
`).join('')
}
`
})
}

View file

@ -1,148 +0,0 @@
let Avatar = {
"useCharacter": true,
"items": [],
"shirt": "https://c0.ptacdn.com/assets/uWrrnFGwgNN5W171vqYTWY7E639rKiXK.png",
"pants": "https://c0.ptacdn.com/assets/HD6TFdXD8CaflRNmd84VCNyNsmTB0SH3.png",
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
const Style = document.createElement('style')
Style.innerHTML = `
html:has(.polyplus-modal[open]), body:has(.polyplus-modal[open]) {
overflow: hidden;
}
.polyplus-modal::backdrop {
background: rgba(0, 0, 0, 0.73);
}
`
document.body.prepend(Style)
const ItemType = document.getElementsByClassName('px-4 px-lg-0 text-muted text-uppercase mb-3')[0].innerText.toLowerCase().split(' ')[1]
const ItemThumbnail = document.getElementsByClassName('store-thumbnail')[0]
const IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
const TryIFrame = document.createElement('iframe')
TryIFrame.setAttribute('style', 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px;')
const TryOnBtn = document.createElement('button')
TryOnBtn.classList = 'btn btn-outline-warning'
TryOnBtn.setAttribute('style', 'position: absolute; bottom: 15px;')
TryOnBtn.innerHTML = '<i class="fa-duotone fa-vial"></i>'
TryOnBtn.addEventListener('click', function (){
TryOnModal.showModal()
});
if (typeof(document.getElementsByClassName('3dviewtoggler')[0]) === 'object') {
TryOnBtn.style.right = '60px'
} else {
TryOnBtn.style.right = '10px'
}
let TryOnModal = document.createElement('dialog')
TryOnModal.classList = 'polyplus-modal'
TryOnModal.setAttribute('style', 'width: 450px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;')
TryOnModal.innerHTML = `
<div class="text-muted mb-2" style="font-size: 0.8rem;">
<h5 class="mb-0" style="color: #fff;">Preview</h5>
Try on this item!
</div>
<div class="modal-body">
<button class="btn btn-primary w-100 mx-auto" onclick="this.parentElement.parentElement.close();">Close</button>
</div>
`
document.body.prepend(TryOnModal)
ItemThumbnail.parentElement.appendChild(TryOnBtn)
TryOnModal.children[1].prepend(TryIFrame)
fetch("https://api.polytoria.com/v1/users/:id/avatar".replace(':id', JSON.parse(window.localStorage.getItem('account_info')).ID))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
data.assets.forEach(item => {
switch (item.type) {
case 'hat':
Avatar.items[Avatar.items.length] = item.path || ''
break
case 'face':
Avatar.face = item.path || ''
break
case 'tool':
Avatar.tool = item.path || ''
break
case 'shirt':
Avatar.shirt = item.path || ''
break
case 'pants':
Avatar.pants = item.path || ''
break
}
});
Avatar.headColor = "#" + data.colors.head
Avatar.torsoColor = "#" + data.colors.torso
Avatar.leftArmColor = "#" + data.colors.leftArm
Avatar.rightArmColor = "#" + data.colors.rightArm
Avatar.leftLegColor = "#" + data.colors.leftLeg
Avatar.rightLegColor = "#" + data.colors.rightLeg
if (ItemType === 'hat' || ItemType === 'tool') {
fetch("https://api.polytoria.com/v1/assets/serve-mesh/:id".replace(':id', window.location.pathname.split('/')[2]))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
if (ItemType === 'hat') {
Avatar.items[Avatar.items.length] = data.url
} else if (ItemType === 'tool') {
Avatar.tool = data.url
}
console.log(Avatar)
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
})
.catch(error => {
console.error('Fetch error:', error);
});
} else {
fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', window.location.pathname.split('/')[2]))
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
switch (ItemType) {
case 'shirt':
Avatar.shirt = data.url
break
case 'pants':
Avatar.pants = data.url
break
case 'face':
Avatar.face = data.url
break
}
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
})
.catch(error => {
console.error('Fetch error:', error);
});
}
})
.catch(error => {
console.error('Fetch error:', error);
});

View file

@ -92,7 +92,7 @@
},
{
"matches": ["https://polytoria.com/my/settings/transactions"],
"matches": ["https://polytoria.com/my/settings/transactions*"],
"js": ["/js/account/transactions.js"]
},

View file

@ -1,11 +0,0 @@
<!doctype html>
<html style="border-radius: 20px;">
<head>
<title>Poly+</title>
</head>
<body>
<div style="text-align: center; width: 300px; padding: 10px;">
<a class="btn" href="https://polytoria.com/my/settings/polyplus">Settings</a>
</div>
</body>
</html>

View file

@ -492,6 +492,15 @@
<br>
<span class="desc">Hide the ugly blue "Upgrade" button on the sidebar!</span>
</p>
<p class="setting-container" id="try-on-items">
<span class="indicator">&nbsp;</span>
<span class="title">
Try-On Items
<button class="btn btn-sm toggle-btn" data-setting="TryOnItemsOn">Toggle</button>
</span>
<br>
<span class="desc">See how that new item looks on your avatar before spending your bricks!</span>
</p>
<p class="setting-container" id="outfit-cost">
<span class="indicator">&nbsp;</span>
<span class="title">
@ -512,6 +521,15 @@
<br>
<span style="font-size: 0.8rem; color: orange;">* Gamepass revenue is calculated assuming the price hasn't changed and all users that bought the gamepass, bought it at the same price that it is at the time of calculating.</span>
</p>
<p class="setting-container" id="item-replace-sales">
<span class="indicator">&nbsp;</span>
<span class="title">
Show "Owners" instead of "Sales"
<button class="btn btn-sm toggle-btn" data-setting="ReplaceItemSalesOn">Toggle</button>
</span>
<br>
<span class="desc">Replace the "Sales" statistic with the "Owners" statistic if the item has 0 sales (most likely meaning it is an item awarded by staff).</span>
</p>
<div class="card">
<div class="card-body">
<h3>EXPERIMENTAL SETTINGS</h3>
@ -556,6 +574,17 @@
<br>
<span style="font-size: 0.8rem; color: orange;">* The styling for this feature is not yet done.</span>
</p>
<p class="setting-container" id="event-items-store">
<span class="indicator">&nbsp;</span>
<span class="title">
"Event Items" Store Category
<button class="btn btn-sm toggle-btn" data-setting="EventItemsCatOn">Toggle</button>
</span>
<br>
<span class="desc">List all the on-going and past event items separated by their event with a store category!</span>
<br>
<span style="font-size: 0.8rem; color: orange;">* This feature is expected to break when messing with store filters.</span>
</p>
</div>
</div>
<hr>