From eeaafeb35a225560788ef512e6fd89d98aa8ffe7 Mon Sep 17 00:00:00 2001 From: Index Date: Sat, 20 Apr 2024 11:58:00 -0500 Subject: [PATCH] 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 --- installation.html | 8 - js/account/friends.js | 382 ++++++++++++++++----------------- js/account/home.js | 18 +- js/account/settings-privacy.js | 2 - js/account/trades-outbound.js | 1 - js/account/transactions.js | 11 +- js/background.js | 79 +++---- js/debug.js | 2 +- js/everywhere.js | 20 +- js/places/place-view.js | 54 ++--- js/resources/utils.js | 21 +- js/store/item-view.js | 207 ++++++++++++++++-- js/store/store.js | 98 ++++++++- js/store/try-on.js | 148 ------------- manifest.json | 2 +- popup.html | 11 - settings.html | 29 +++ 17 files changed, 618 insertions(+), 475 deletions(-) delete mode 100755 installation.html delete mode 100755 js/store/try-on.js delete mode 100755 popup.html diff --git a/installation.html b/installation.html deleted file mode 100755 index 36b8464..0000000 --- a/installation.html +++ /dev/null @@ -1,8 +0,0 @@ - - - Poly+ - - -

Thank you for installing Poly+!

- - \ No newline at end of file diff --git a/js/account/friends.js b/js/account/friends.js index fec1777..16ef210 100755 --- a/js/account/friends.js +++ b/js/account/friends.js @@ -1,212 +1,210 @@ var SelectedFriends = [] -setTimeout(function () { - chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ - Settings = result.PolyPlus_Settings; - if (Settings.ImprovedFrListsOn === true) { - var Tab = "requests" +chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ + Settings = result.PolyPlus_Settings; + if (Settings.ImprovedFrListsOn === true) { + var Tab = "requests" - var FriendsContainer = document.getElementById('friends-container') - var Container = document.createElement('div') - Container.classList = 'row mb-3' - Container.innerHTML = ` -
-
- ` - FriendsContainer.parentElement.insertBefore(Container, FriendsContainer) - var AccAllFrBtn = document.getElementById('AccAllFrBtn') - var DelAllFrBtn = document.getElementById('DelAllFrBtn') - var AccBtns = document.querySelectorAll('[onclick="acceptFriendRequest(this)"]') - var DelBtns = document.querySelectorAll('[onclick="declineFriendRequest(this)"]') - if (!(AccBtns.length === 0)) { - AccAllFrBtn.addEventListener('click', function(){ - AccBtns.forEach(element => { - setTimeout(function () {}, 145) - fetch('https://polytoria.com/api/friends/send', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value - }, - body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }), - }) - .catch(error => { - // Handle any errors - console.error('Error:', error); - Success = false - }); - - /* - let NewAcceptBtn = document.createElement('a') - NewAcceptBtn.style.display = 'none' - sNewAcceptBtn.classList = 'btn btn-success' - NewAcceptBtn.setAttribute('data-user-id', element.getAttribute('data-user-id')) - NewAcceptBtn.setAttribute('onclick', 'acceptFriendRequest(this)') - FriendsContainer.appendChild(NewAcceptBtn) - NewAcceptBtn.click(); - */ + var FriendsContainer = document.getElementById('friends-container') + var Container = document.createElement('div') + Container.classList = 'row mb-3' + Container.innerHTML = ` +
+
+ ` + FriendsContainer.parentElement.insertBefore(Container, FriendsContainer) + var AccAllFrBtn = document.getElementById('AccAllFrBtn') + var DelAllFrBtn = document.getElementById('DelAllFrBtn') + var AccBtns = document.querySelectorAll('[onclick="acceptFriendRequest(this)"]') + var DelBtns = document.querySelectorAll('[onclick="declineFriendRequest(this)"]') + if (!(AccBtns.length === 0)) { + AccAllFrBtn.addEventListener('click', function(){ + AccBtns.forEach(element => { + setTimeout(function () {}, 145) + fetch('https://polytoria.com/api/friends/send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value + }, + body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }), }) - }); - } else { - AccAllFrBtn.setAttribute('disabled', 'true') - } - if (!(DelBtns.length === 0)) { - DelAllFrBtn.addEventListener('click', function(){ - DelBtns.forEach(element => { - setTimeout(function () {}, 110) - fetch('https://polytoria.com/api/friends/remove', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value - }, - body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }), - }) - .catch(error => { - // Handle any errors - console.error('Error:', error, document.querySelector('input[name="_csrf"]').value); - Success = false - }); + .catch(error => { + // Handle any errors + console.error('Error:', error); + Success = false + }); - /* + /* + let NewAcceptBtn = document.createElement('a') + NewAcceptBtn.style.display = 'none' + sNewAcceptBtn.classList = 'btn btn-success' + NewAcceptBtn.setAttribute('data-user-id', element.getAttribute('data-user-id')) + NewAcceptBtn.setAttribute('onclick', 'acceptFriendRequest(this)') + FriendsContainer.appendChild(NewAcceptBtn) + NewAcceptBtn.click(); + */ + }) + }); + } else { + AccAllFrBtn.setAttribute('disabled', 'true') + } + if (!(DelBtns.length === 0)) { + DelAllFrBtn.addEventListener('click', function(){ + DelBtns.forEach(element => { + setTimeout(function () {}, 110) + fetch('https://polytoria.com/api/friends/remove', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value + }, + body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }), + }) + .catch(error => { + // Handle any errors + console.error('Error:', error, document.querySelector('input[name="_csrf"]').value); + Success = false + }); + + /* + let NewDeclineBtn = document.createElement('a') + NewDeclineBtn.style.display = 'none' + NewDeclineBtn.classList = 'btn btn-danger' + NewDeclineBtn.setAttribute('data-user-id', element.getAttribute('data-user-id')) + NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)') + FriendsContainer.appendChild(NewDeclineBtn) + NewDeclineBtn.click(); + */ + }) + }); + } else { + DelAllFrBtn.setAttribute('disabled', 'true') + } + let Text = document.createElement('p') + Text.classList = 'mx-auto' + Text.style.textAlign = 'center' + Text.style.fontSize = '1.3rem' + Text.style.display = 'none' + Text.innerHTML = ` + 0 friends selected! +
+ + + + ` + FriendsContainer.parentElement.insertBefore(Text, FriendsContainer) + let Text_Span = Text.querySelector('span'); + let Text_View = document.getElementById('viewSelectionBtn'); + let Text_Clear = document.getElementById('clearSelectionBtn'); + let Text_Remove = document.getElementById('removeSelectionBtn'); + document.querySelector('[data-friends-tab="requests"]').addEventListener('click', function(){ + Tab = "requests" + Container.style.display = ''; + Text.style.display = 'none'; + document.querySelectorAll('input[type="check"]').forEach(element => {element.remove();}); + }); + document.querySelector('[data-friends-tab="friends"]').addEventListener('click', function(){ + Tab = "friends" + Container.style.display = 'none'; + Text.style.display = ''; + }); + var ConfirmRemove = 0 + Text_View.addEventListener('click', function(){}); + Text_Clear.addEventListener('click', function(){ + SelectedFriends = [] + UpdateCheckboxes(); + Text_Span.innerText = SelectedFriends.length + }); + Text_Remove.addEventListener('click', function(){ + ConfirmRemove = ConfirmRemove + 1 + switch(ConfirmRemove) { + case 0: + Text_Remove.innerText = 'Remove Selected Friends' + break + case 1: + Text_Remove.innerText = 'Are you sure?' + break + case 2: + for (let i = 0; i < SelectedFriends.length; i++) { + setTimeout(function () {}, 110) let NewDeclineBtn = document.createElement('a') NewDeclineBtn.style.display = 'none' NewDeclineBtn.classList = 'btn btn-danger' - NewDeclineBtn.setAttribute('data-user-id', element.getAttribute('data-user-id')) + NewDeclineBtn.setAttribute('data-user-id', SelectedFriends[i]) NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)') FriendsContainer.appendChild(NewDeclineBtn) NewDeclineBtn.click(); - */ - }) - }); - } else { - DelAllFrBtn.setAttribute('disabled', 'true') + } + SelectedFriends = [] + UpdateCheckboxes(); + Text_Remove.innerText = 'Remove Selected Friends' + ConfirmRemove = 0 + break } - let Text = document.createElement('p') - Text.classList = 'mx-auto' - Text.style.textAlign = 'center' - Text.style.fontSize = '1.3rem' - Text.style.display = 'none' - Text.innerHTML = ` - 0 friends selected! -
- - - - ` - FriendsContainer.parentElement.insertBefore(Text, FriendsContainer) - let Text_Span = Text.querySelector('span'); - let Text_View = document.getElementById('viewSelectionBtn'); - let Text_Clear = document.getElementById('clearSelectionBtn'); - let Text_Remove = document.getElementById('removeSelectionBtn'); - document.querySelector('[data-friends-tab="requests"]').addEventListener('click', function(){ - Tab = "requests" - Container.style.display = ''; - Text.style.display = 'none'; - document.querySelectorAll('input[type="check"]').forEach(element => {element.remove();}); - }); - document.querySelector('[data-friends-tab="friends"]').addEventListener('click', function(){ - Tab = "friends" - Container.style.display = 'none'; - Text.style.display = ''; - }); - var ConfirmRemove = 0 - Text_View.addEventListener('click', function(){}); - Text_Clear.addEventListener('click', function(){ - SelectedFriends = [] - UpdateCheckboxes(); - Text_Span.innerText = SelectedFriends.length - }); - Text_Remove.addEventListener('click', function(){ - ConfirmRemove = ConfirmRemove + 1 - switch(ConfirmRemove) { - case 0: - Text_Remove.innerText = 'Remove Selected Friends' - break - case 1: - Text_Remove.innerText = 'Are you sure?' - break - case 2: - for (let i = 0; i < SelectedFriends.length; i++) { - setTimeout(function () {}, 110) - let NewDeclineBtn = document.createElement('a') - NewDeclineBtn.style.display = 'none' - NewDeclineBtn.classList = 'btn btn-danger' - NewDeclineBtn.setAttribute('data-user-id', SelectedFriends[i]) - NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)') - FriendsContainer.appendChild(NewDeclineBtn) - NewDeclineBtn.click(); - } - SelectedFriends = [] - UpdateCheckboxes(); - Text_Remove.innerText = 'Remove Selected Friends' - ConfirmRemove = 0 - break - } - }); + }); - const observer = new MutationObserver(function (){ - if (FriendsContainer.children.length > 0 && Tab === "friends") { - LoadCheckBoxes(); - } - }); - observer.observe(FriendsContainer, {childList: true, subtree: false}); + const observer = new MutationObserver(function (){ + if (FriendsContainer.children.length > 0 && Tab === "friends") { + LoadCheckBoxes(); + } + }); + observer.observe(FriendsContainer, {childList: true, subtree: false}); - function LoadCheckBoxes() { - Array.from(FriendsContainer.children).forEach(element => { - let DeclineBtn = element.querySelector('a.btn.btn-danger') - let UserID = DeclineBtn.getAttribute('data-user-id') - let Column = document.createElement('div') - let EditColumn = element.querySelector('.col-9') - Column.classList = 'col-auto' - var NewCheckBox = document.createElement('button') - NewCheckBox.classList = 'polyplus-multiremovefr-checkbox' - NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem;') + function LoadCheckBoxes() { + Array.from(FriendsContainer.children).forEach(element => { + let DeclineBtn = element.querySelector('a.btn.btn-danger') + let UserID = DeclineBtn.getAttribute('data-user-id') + let Column = document.createElement('div') + let EditColumn = element.querySelector('.col-9') + Column.classList = 'col-auto' + var NewCheckBox = document.createElement('button') + NewCheckBox.classList = 'polyplus-multiremovefr-checkbox' + NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem;') + var Index = SelectedFriends.indexOf(UserID) + if (Index !== -1) { + DeclineBtn.classList.add('disabled') + NewCheckBox.style.borderColor = 'lime' + } + EditColumn.classList.remove('col-9') + EditColumn.classList.add('col') + Column.appendChild(NewCheckBox) + EditColumn.parentElement.appendChild(Column) + NewCheckBox.addEventListener('click', function(){ var Index = SelectedFriends.indexOf(UserID) - if (Index !== -1) { + if (Index === -1) { DeclineBtn.classList.add('disabled') + SelectedFriends.push(UserID) NewCheckBox.style.borderColor = 'lime' - } - EditColumn.classList.remove('col-9') - EditColumn.classList.add('col') - Column.appendChild(NewCheckBox) - EditColumn.parentElement.appendChild(Column) - NewCheckBox.addEventListener('click', function(){ - var Index = SelectedFriends.indexOf(UserID) - if (Index === -1) { - DeclineBtn.classList.add('disabled') - SelectedFriends.push(UserID) - NewCheckBox.style.borderColor = 'lime' - } else { - SelectedFriends.splice(Index, 1) - NewCheckBox.style.borderColor = '#393939' - DeclineBtn.classList.remove('disabled') - } - Text_Span.innerText = SelectedFriends.length - UpdateCheckboxes(); - }); - }); - } - - function UpdateCheckboxes(){ - document.querySelectorAll('.polyplus-multiremovefr-checkbox').forEach(element => { - let Parent = element.parentElement.parentElement.parentElement.parentElement.parentElement - let DeclineBtn = Parent.querySelector('a.btn.btn-danger') - if (element.getAttribute('disabled')) { - element.removeAttribute('disabled') - } - if (SelectedFriends.IndexOf(DeclineBtn.getAttribute('data-user-id')) === -1) { - element.style.borderColor = '#393939' - DeclineBtn.classList.remove('disabled') - if (SelectedFriends.length >= 25) { - element.setAttribute('disabled', true) - } } else { - DeclineBtn.classList.add('disabled') - element.style.borderColor = 'lime' + SelectedFriends.splice(Index, 1) + NewCheckBox.style.borderColor = '#393939' + DeclineBtn.classList.remove('disabled') } - }) - } + Text_Span.innerText = SelectedFriends.length + UpdateCheckboxes(); + }); + }); } - }); -}, 100); \ No newline at end of file + + function UpdateCheckboxes(){ + document.querySelectorAll('.polyplus-multiremovefr-checkbox').forEach(element => { + let Parent = element.parentElement.parentElement.parentElement.parentElement.parentElement + let DeclineBtn = Parent.querySelector('a.btn.btn-danger') + if (element.getAttribute('disabled')) { + element.removeAttribute('disabled') + } + if (SelectedFriends.IndexOf(DeclineBtn.getAttribute('data-user-id')) === -1) { + element.style.borderColor = '#393939' + DeclineBtn.classList.remove('disabled') + if (SelectedFriends.length >= 25) { + element.setAttribute('disabled', true) + } + } else { + DeclineBtn.classList.add('disabled') + element.style.borderColor = 'lime' + } + }) + } + } +}); \ No newline at end of file diff --git a/js/account/home.js b/js/account/home.js index 84ceaff..af83351 100755 --- a/js/account/home.js +++ b/js/account/home.js @@ -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] - const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrencyCurrency) + 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.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")" - Price.appendChild(Span) + let Span = document.createElement('span') + Span.classList = 'text-muted polyplus-price-tag' + Span.style = 'font-size: 0.7rem; font-weight: lighter;' + Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")" + Price.appendChild(Span) + } } })(); } \ No newline at end of file diff --git a/js/account/settings-privacy.js b/js/account/settings-privacy.js index 78258c2..d3762e9 100755 --- a/js/account/settings-privacy.js +++ b/js/account/settings-privacy.js @@ -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] diff --git a/js/account/trades-outbound.js b/js/account/trades-outbound.js index 270301c..10fecdf 100755 --- a/js/account/trades-outbound.js +++ b/js/account/trades-outbound.js @@ -1,4 +1,3 @@ -setTimeout(function() {}, 100) var SelectedTrades = [] let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement diff --git a/js/account/transactions.js b/js/account/transactions.js index 92a69fd..ce475ec 100755 --- a/js/account/transactions.js +++ b/js/account/transactions.js @@ -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 = ` @@ -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 } diff --git a/js/background.js b/js/background.js index 462b459..bd95f2f 100755 --- a/js/background.js +++ b/js/background.js @@ -71,45 +71,48 @@ function RunUpdateNotifier() { } }); } -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({ - title: 'Copy Asset ID', - id: 'PolyPlus-CopyID', - contexts: ['link'], - documentUrlPatterns: [ - "https://polytoria.com/*", - SettingsURL - ], - targetUrlPatterns: [ - "https://polytoria.com/places/**", - "https://polytoria.com/users/**", - "https://polytoria.com/store/**" - ] -}); - -// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION -chrome.contextMenus.create({ - title: 'Copy Avatar Hash', - id: 'PolyPlus-CopyAvatarHash', - contexts: ['image'], - documentUrlPatterns: [ - "https://polytoria.com/*", - SettingsURL - ], - targetUrlPatterns: [ - "https://c0.ptacdn.com/thumbnails/avatars/**", - "https://c0.ptacdn.com/thumbnails/avatars/**" - ] -}); +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({ + title: 'Copy Asset ID', + id: 'PolyPlus-CopyID', + contexts: ['link'], + documentUrlPatterns: [ + "https://polytoria.com/*", + SettingsURL + ], + targetUrlPatterns: [ + "https://polytoria.com/places/**", + "https://polytoria.com/users/**", + "https://polytoria.com/store/**" + ] + }); + + // COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION + chrome.contextMenus.create({ + title: 'Copy Avatar Hash', + id: 'PolyPlus-CopyAvatarHash', + contexts: ['image'], + documentUrlPatterns: [ + "https://polytoria.com/*", + SettingsURL + ], + targetUrlPatterns: [ + "https://c0.ptacdn.com/thumbnails/avatars/**", + "https://c0.ptacdn.com/thumbnails/avatars/**" + ] + }); +}) // HANDLE CONTEXT MENU ITEMS chrome.contextMenus.onClicked.addListener(function (info, tab){ diff --git a/js/debug.js b/js/debug.js index a59d6d7..1a8be14 100644 --- a/js/debug.js +++ b/js/debug.js @@ -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() }); \ No newline at end of file diff --git a/js/everywhere.js b/js/everywhere.js index f34140d..0bf5814 100755 --- a/js/everywhere.js +++ b/js/everywhere.js @@ -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 += `` } + + const ThemeBlob = new Blob([Theme], { type: 'text/css' }) + const ThemeURL = window.URL.createObjectURL(ThemeBlob) + document.head.innerHTML += `` }); document.addEventListener('DOMContentLoaded', async function() { diff --git a/js/places/place-view.js b/js/places/place-view.js index 25d56ab..677246e 100644 --- a/js/places/place-view.js +++ b/js/places/place-view.js @@ -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,30 +421,30 @@ 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) { - const PriceAfterTax = Math.floor(gamepass.asset.price - (gamepass.asset.price * CreatorTax)) - Revenue += (PriceAfterTax * gamepass.asset.sales) - } + let Achievements = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/achievements') + Achievements = await Achievements.json() - const ResultText = document.createElement('li') - ResultText.classList = 'fw-normal text-success' - ResultText.style.letterSpacing = '0px' - ResultText.innerHTML = ` ~` + Revenue.toLocaleString() - - CalculateRevenueButton.remove() - InfoColumns[1].appendChild(ResultText) - }) - .catch(error => { - console.log(error) - }); + 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' + ResultText.innerHTML = ` ~` + Revenue.toLocaleString() + + CalculateRevenueButton.remove() + InfoColumns[1].appendChild(ResultText) } function round5(number) { const remainder = number % 5; if (remainder < 2.5) { return number - remainder; } else { return number + (5 - remainder); } } diff --git a/js/resources/utils.js b/js/resources/utils.js index 112d553..f68971f 100644 --- a/js/resources/utils.js +++ b/js/resources/utils.js @@ -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 } diff --git a/js/store/item-view.js b/js/store/item-view.js index 0189d1e..e32bd04 100755 --- a/js/store/item-view.js +++ b/js/store/item-view.js @@ -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,16 +95,14 @@ 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' - Span.style.fontSize = '0.7rem' - Span.style.fontWeight = 'normal' - const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrencyCurrency) - Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")" - PurchaseBtn.appendChild(Span) - } + const Price = PurchaseBtn.getAttribute('data-price') + const Span = document.createElement('span') + Span.classList = 'text-muted polyplus-own-tag' + Span.style.fontSize = '0.7rem' + Span.style.fontWeight = 'normal' + const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrencyCurrency) + Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")" + PurchaseBtn.appendChild(Span) } function HandleItemWishlist() { @@ -136,4 +168,145 @@ function HandleItemWishlist() { DescriptionText.appendChild(document.createElement('br')) 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 = '' + 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 = ` +
+
Preview
+ Try on this item! +
+ + ` + + 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); + }); } \ No newline at end of file diff --git a/js/store/store.js b/js/store/store.js index 5d36a6f..c26fff6 100755 --- a/js/store/store.js +++ b/js/store/store.js @@ -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 = ` + + + ` + 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) => ` +
+
+
${x.date}
+
${x.name}
+
+
+
+
+
+ ${ + x.items.map((x) => ` + +
+
+ +
+
+ ${x.name} +
+
+
+
+
+ `).join('') + } +
+
+
+ + `).join('') + } + ` + }) +} \ No newline at end of file diff --git a/js/store/try-on.js b/js/store/try-on.js deleted file mode 100755 index 2f6a8c5..0000000 --- a/js/store/try-on.js +++ /dev/null @@ -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 = '' -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 = ` -
-
Preview
- Try on this item! -
- -` - -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); - }); \ No newline at end of file diff --git a/manifest.json b/manifest.json index bd9966c..65ea5bf 100755 --- a/manifest.json +++ b/manifest.json @@ -92,7 +92,7 @@ }, { - "matches": ["https://polytoria.com/my/settings/transactions"], + "matches": ["https://polytoria.com/my/settings/transactions*"], "js": ["/js/account/transactions.js"] }, diff --git a/popup.html b/popup.html deleted file mode 100755 index a6151c7..0000000 --- a/popup.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - Poly+ - - -
- Settings -
- - \ No newline at end of file diff --git a/settings.html b/settings.html index b56fb82..b190e31 100755 --- a/settings.html +++ b/settings.html @@ -492,6 +492,15 @@
Hide the ugly blue "Upgrade" button on the sidebar!

+

+   + + Try-On Items + + +
+ See how that new item looks on your avatar before spending your bricks! +

  @@ -512,6 +521,15 @@
* 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.

+

+   + + Show "Owners" instead of "Sales" + + +
+ Replace the "Sales" statistic with the "Owners" statistic if the item has 0 sales (most likely meaning it is an item awarded by staff). +

EXPERIMENTAL SETTINGS

@@ -556,6 +574,17 @@
* The styling for this feature is not yet done.

+

+   + + "Event Items" Store Category + + +
+ List all the on-going and past event items separated by their event with a store category! +
+ * This feature is expected to break when messing with store filters. +