From c1bee43f08c760644b9cc35a98d58de9cfc319de Mon Sep 17 00:00:00 2001 From: Index Date: Wed, 22 May 2024 17:18:55 -0500 Subject: [PATCH] prepare for next update i don't feel like writing github commit description right now --- js/account/avatar-sandbox2.js | 75 ++++- js/account/home.js | 23 ++ js/account/profile.js | 33 ++- js/everywhere.js | 33 +-- js/guilds.js | 18 -- js/library-download.js | 2 - js/op-comments.js | 90 +++--- js/places/place-view.js | 82 ++---- js/settings.js | 2 +- js/store/item-view.js | 516 +++++++++++++++++----------------- js/store/store.js | 52 +++- manifest.json | 14 +- resources/avatar-sandbox.html | 5 +- resources/registerTooltips.js | 3 +- resources/utils.js | 56 +++- settings.html | 46 ++- settings.js | 87 +++++- 17 files changed, 676 insertions(+), 461 deletions(-) diff --git a/js/account/avatar-sandbox2.js b/js/account/avatar-sandbox2.js index 9a1a070..60cca8a 100755 --- a/js/account/avatar-sandbox2.js +++ b/js/account/avatar-sandbox2.js @@ -1,5 +1,70 @@ -setTimeout(function () {}, 100) const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID +const BodyColors = [ + "#f8f8f8", + "#cdcdcd", + "#111111", + "#ff0000", + "#a34b4b", + "#ffc9c9", + "#957977", + "#c4281c", + "#da867a", + "#694028", + "#cc8e69", + "#a05f35", + "#7c5c46", + "#eab892", + "#da8541", + "#aa5500", + "#ffcc99", + "#e29b40", + "#ffaf00", + "#ffb000", + "#d7c59a", + "#f5cd30", + "#fdea8d", + "#e5e4df", + "#c1be42", + "#ffff00", + "#ffffcc", + "#a4bd47", + "#7f8e64", + "#a1c48c", + "#3a7d15", + "#4b974b", + "#00ff00", + "#ccffcc", + "#27462d", + "#287f47", + "#789082", + "#9ff3e9", + "#12eed4", + "#f2f3f3", + "#00ffff", + "#008f9c", + "#04afec", + "#80bbdb", + "#b4d2e4", + "#0d69ac", + "#1b2a35", + "#afddff", + "#6e99ca", + "#74869d", + "#2154b9", + "#002060", + "#0000ff", + "#b1a7ff", + "#a3a2a5", + "#6225d1", + "#b480ff", + "#8c5b9f", + "#6b327c", + "#aa00aa", + "#635f62", + "#ff00bf", + "#ff66cc", + "#e8bac8" +] let PageContainer = document.querySelector('.container.p-0.p-lg-5') let ItemGrid; @@ -24,7 +89,7 @@ let Avatar = { "rightLegColor": "#e0e0e0" } -if (new URLSearchParams(new URL(window.location).search).get('sandbox') === 'true') { +if (new URLSearchParams(window.location.search).has('sandbox')) { console.log('Avatar Sandbox!') LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function(html){ @@ -110,6 +175,12 @@ if (new URLSearchParams(new URL(window.location).search).get('sandbox') === 'tru UpdateAvatar() }); }); +} else { + const SandboxButton = document.createElement('a') + SandboxButton.classList = 'btn btn-outline-success w-100 mt-3' + SandboxButton.href = '?sandbox=true' + SandboxButton.innerHTML = ' Avatar Sandbox' + document.getElementById('cont-move').parentElement.appendChild(SandboxButton) } function UpdateAvatar() { diff --git a/js/account/home.js b/js/account/home.js index 30c908b..b60b5d4 100755 --- a/js/account/home.js +++ b/js/account/home.js @@ -15,6 +15,10 @@ chrome.storage.sync.get(['PolyPlus_Settings'], async function(result) { IRLPrice() } + if (Settings.ShowFriendCount === true) { + ShowFriendCount() + } + if (Settings.PinnedGamesOn === true || Settings.BestFriendsOn === true) { Update() } @@ -189,4 +193,23 @@ async function IRLPrice() { } } })(); +} + +async function ShowFriendCount() { + let FriendCount = (await (await fetch('https://polytoria.com/api/friends?page=1')).json()).meta.total + /* + const FirstPage = (await (await fetch('https://polytoria.com/api/friends?page=1')).json()) + if (FirstPage.meta.lastPage > 1) { + const LastPage = (await (await fetch('https://polytoria.com/api/friends?page=' + Pages)).json()) + FriendCount = (12*(FirstPage.meta.pages-1)) + LastPage.data.length + } else { + FriendCount = FirstPage.data.length + } + */ + + const CountText = document.createElement('small') + CountText.classList = 'text-muted fw-lighter' + CountText.style.fontSize = '0.8rem' + CountText.innerText = ' (' + FriendCount + ')' + document.querySelector('#home-friendsOnline h5').appendChild(CountText) } \ No newline at end of file diff --git a/js/account/profile.js b/js/account/profile.js index 0a50e1a..d2ffc39 100755 --- a/js/account/profile.js +++ b/js/account/profile.js @@ -1,4 +1,4 @@ -const UserID = window.location.pathname.split('/')[2]; +let UserID = window.location.pathname.split('/')[2]; const AvatarRow = document.getElementsByClassName('d-flex flex-row flex-nowrap overflow-x-scroll px-3 px-lg-0 mb-2 mb-lg-0')[0] const AvatarHeading = document.querySelector('.section-title:has(i.fa-user-crown)') @@ -9,8 +9,9 @@ let CalculateButton; let Utilities; -if (UserID && !isNaN(UserID)) { +if (UserID) { (async () => { + UserID = (await (await fetch('https://api.polytoria.com/v1/users/')).json()).id Utilities = await import(chrome.runtime.getURL('resources/utils.js')); Utilities = Utilities.default @@ -94,15 +95,15 @@ if (UserID && !isNaN(UserID)) { } else if (UserID && UserID[0] === "@") { const Username = window.location.pathname.split('/')[2].substring(1) - let Reference = new URLSearchParams(new URL(window.location.href).search).get('ref') - if (Reference === null) { + let Reference = new URLSearchParams(new URL(window.location.href).search) + if (!Reference.has('ref')) { Reference = "" } fetch("https://api.polytoria.com/v1/users/find?username=" + Username) .then(response => { if (!response.ok) { - window.location.href = window.location.origin + decodeURIComponent(Reference) + window.location.href = window.location.origin + decodeURIComponent(Reference.get('ref')) } else { return response.json() } @@ -127,14 +128,14 @@ function BestFriends() { FavoriteBtn = document.createElement('button'); FavoriteBtn.classList = 'btn btn-warning btn-sm ml-2'; - if (!(BestFriends.length === 7)) { + if (!(BestFriends.length === Utilities.Limits.BestFriends)) { if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID))) { FavoriteBtn.innerText = 'Remove Best Friend Status'; } else { FavoriteBtn.innerText = 'Best Friend'; } } else { - FavoriteBtn.innerText = 'Remove Best Friend Status (max 7/7)' + FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')' } if (UserID !== JSON.parse(window.localStorage.getItem('account_info')).ID && document.getElementById('add-friend-button').classList.contains('btn-success') === false) { FavoriteBtn.addEventListener('click', function() { @@ -180,14 +181,14 @@ function BestFriends() { chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result) { BestFriends = result.PolyPlus_BestFriends || []; - if (!(BestFriends.length === 7)) { + if (!(BestFriends.length === Utilities.Limits.BestFriends)) { if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID))) { FavoriteBtn.innerText = 'Remove Best Friend Status' } else { FavoriteBtn.innerText = 'Best Friend' } } else { - FavoriteBtn.innerText = 'Remove Best Friend Status (max 7/7)' + FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')' } }); } @@ -206,8 +207,9 @@ function BestFriends() { async function OutfitCost() { const AvatarCost = { Total: 0, - Limiteds: 0, - Exclusives: 0 + Collectibles: 0, + Offsale: 0, + HasProfileTheme: false } for (let item of AvatarRow.children) { const ItemID = item.getElementsByTagName('a')[0].href.split('/')[4] @@ -221,10 +223,13 @@ async function OutfitCost() { .then(data => { let Price = data.price if (data.isLimited === true) { - AvatarCost.Limiteds += 1 + AvatarCost.Collectibles += 1 Price = data.averagePrice } else if (data.sales === 0) { - AvatarCost.Exclusives += 1 + AvatarCost.Offsale += 1 + Price = 0 + } else if (data.type === 'profileTheme') { + AvatarCost.HasProfileTheme = true Price = 0 } @@ -235,7 +240,7 @@ async function OutfitCost() { const ResultText = document.createElement('small') ResultText.classList = 'fw-normal text-success' ResultText.style.letterSpacing = '0px' - ResultText.innerHTML = `( ${ (AvatarCost.Limiteds > 0 || AvatarCost.Exclusives > 0) ? '~' : '' }${ AvatarCost.Total.toLocaleString() }${ (AvatarCost.Limiteds > 0) ? `, ${AvatarCost.Limiteds} limited` : '' }${ (AvatarCost.Exclusives > 0) ? `, ${AvatarCost.Exclusives} exclusive` : '' })` + ResultText.innerHTML = `( ${ (AvatarCost.Collectibles > 0 || AvatarCost.Offsale > 0 || AvatarCost.HasProfileTheme === true) ? '~' : '' }${ AvatarCost.Total.toLocaleString() } | ${ (AvatarCost.Collectibles > 0) ? AvatarCost.Collectibles + ' collectible' : '' }${ (AvatarCost.Offsale > 0) ? `, ${AvatarCost.Offsale} offsale` : '' }${ (AvatarCost.HasProfileTheme === true) ? ', profile theme excluded' : '' })` CalculateButton.remove() AvatarHeading.appendChild(ResultText) diff --git a/js/everywhere.js b/js/everywhere.js index 7c09795..af395e6 100755 --- a/js/everywhere.js +++ b/js/everywhere.js @@ -12,7 +12,6 @@ let Theme = null; // If theme exists, create a style element to represent it if (Settings.ThemeCreatorOn && Settings.ThemeCreatorOn === true) { - //Theme = document.createElement('style') switch (Settings.ThemeCreator.BGImageSize) { case 0: Settings.ThemeCreator.BGImageSize = 'fit' @@ -113,8 +112,9 @@ let Theme = null; ` } + // Credit to @SK-Fast (also known as DevPixels) for the improved loading code (taken from his original Poly+, and reformatted to Index Poly+) const ThemeBlob = new Blob([Theme], { type: 'text/css' }) - const ThemeURL = window.URL.createObjectURL(ThemeBlob) + const ThemeURL = URL.createObjectURL(ThemeBlob) document.head.innerHTML += `` }); @@ -137,21 +137,18 @@ let Theme = null; // Define Data const UserData = { - Username: document.querySelector('a.text-reset.text-decoration-none[href^="/users"]').innerText.replace(/\s+/g,''), ID: document.querySelector('.text-reset.text-decoration-none[href^="/users/"]').getAttribute('href').split('/')[2], Bricks: document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g,'') } window.localStorage.setItem('account_info', JSON.stringify(UserData)) document.body.setAttribute('data-URL', window.location.pathname) - - // Add PolyPlus Settings link to Sidebar - const Parent = document.querySelector('ul.nav.nav-flush') - const Clone = Parent.querySelectorAll('li.nav-item')[0].cloneNode(true) - Clone.getElementsByTagName('a')[0].href = '/my/settings/polyplus' - Clone.getElementsByTagName('span')[0].innerText = "Poly+" - const Icon = Clone.querySelector('i') - Icon.classList = 'fa-regular fa-sparkles' + + if (Settings.IRLPriceWithCurrencyOn === true) { + const IRLResult = await Utilities.CalculateIRL(UserData.Bricks, Settings.IRLPriceWithCurrencyCurrency) + const BrickBalanceCount = [document.querySelector('.text-success .brickBalanceCount'), document.querySelector('.text-success .brickBalanceCont')] + BrickBalanceCount.forEach(element => {element.innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`}); + } if (Settings.ModifyNavOn && Settings.ModifyNavOn === true) { let NavbarItems = document.querySelectorAll('.navbar-nav.me-auto a.nav-link[href]') @@ -165,18 +162,8 @@ let Theme = null; } } - if (Settings.HideUpgradeBtnOn && Settings.HideUpgradeBtnOn === true) { - document.querySelector('.nav-sidebar a[href="/upgrade"].nav-link.py-1.nav-sidebar-link').remove() - } - - if (Settings.IRLPriceWithCurrencyOn && Settings.IRLPriceWithCurrencyOn === true) { - const IRLResult = await Utilities.CalculateIRL(UserData.Bricks, Settings.IRLPriceWithCurrencyCurrency) - const BrickBalanceCount = [document.querySelector('.text-success .brickBalanceCount'), document.querySelector('.text-success .brickBalanceCont')] - BrickBalanceCount.forEach(element => {element.innerText = element.innerText + ` ($${IRLResult.result} ${IRLResult.display})`}); - } - - if (Settings.HideNotifBadgesOn && Settings.HideNotifBadgesOn === true) { - document.querySelectorAll('.notif-nav.notif-sidebar').forEach(element => {element.remove();}); + if (Settings.HideNotifBadgesOn === true) { + document.getElementsByClassName('notif-nav notif-sidebar').forEach(element => {element.remove();}); } }); })(); diff --git a/js/guilds.js b/js/guilds.js index 95ba4c3..dbc9c61 100644 --- a/js/guilds.js +++ b/js/guilds.js @@ -23,24 +23,6 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ } }); -/* -async function IRLPrice() { - Array.from(document.getElementsByClassName('polyplus-price-tag')).forEach(tag => {tag.remove()}) - for (let item of Array.from(StoreItems.children)) { - const Price = item.getElementsByClassName('text-success')[0] - if (Price !== undefined && Price.innerText !== "Free") { - 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) - } - } -} -*/ - async function IRLPrice(item) { const Price = item.getElementsByClassName('text-success')[0] if (Price !== undefined && Price.innerText !== "Free") { diff --git a/js/library-download.js b/js/library-download.js index eb88866..2edbb11 100644 --- a/js/library-download.js +++ b/js/library-download.js @@ -7,8 +7,6 @@ const LibraryTypes = [ "Mesh" ] -var Success = true; - if (LibraryTypes.indexOf(LibraryType) !== -1) { chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ Settings = result.PolyPlus_Settings || {}; diff --git a/js/op-comments.js b/js/op-comments.js index 253fa32..e885f62 100755 --- a/js/op-comments.js +++ b/js/op-comments.js @@ -1,56 +1,56 @@ -let Comments = document.getElementById('comments') -const Type = window.location.pathname.split('/')[1] +!(() => { + let Comments = document.getElementById('comments') + const Type = window.location.pathname.split('/')[1] -let CreatorID; -switch (Type) { - case 'store': + let CreatorID; + if (Type === 'store') { if (document.querySelector('h5 .text-reset[href^="/users/"]')) { CreatorID = document.querySelector('h5 .text-reset[href^="/users/"]').getAttribute('href').split('/')[2] - } else {CreatorID = 1} - break - case 'places': + } else { + CreatorID = 1 + } + } else if (Type === 'places') { CreatorID = document.querySelector('.mcard .col .text-muted [href^="/users/"]').getAttribute('href').split('/')[2] - break - /* - case 'feed': + } else if (Type === 'feed') { CreatorID = document.querySelector('p a[href^="/users/"].text-reset').getAttribute('href').split('/')[2] - break - */ - case 'guilds': + } else if (Type === 'guilds') { CreatorID = document.querySelector('[class^="userlink-"][href^="/users/"]').getAttribute('href').split('/')[2] Comments = document.getElementById('wall-posts') - break -} -Array.from(Comments.children).forEach(element => { - LoadCreatorTag(element) -}); + } -const Observer = new MutationObserver(function (list){ - for (let record of list) { - for (let element of record.addedNodes) { - LoadCreatorTag(element) + const Observer = new MutationObserver(function (list){ + for (let record of list) { + for (let element of record.addedNodes) { + if (element.classList === 'card mb-3') { + LoadCreatorTag(element) + } + } + } + }); + Observer.observe(Comments, {attributes: false, childList: true, subtree: false}) + + const LoadCreatorTag = function(element) { + console.log(element) + let NameElement = element.querySelector('.text-reset[href^="/users/"]') + if (Type === 'guilds') { + NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]') + } + + let UserID = NameElement.getAttribute('href').split('/')[2] + if (UserID === CreatorID) { + let Tag = document.createElement('span') + Tag.classList = 'badge bg-primary' + Tag.style.marginLeft = '5px' + Tag.style.verticalAlign = 'text-top' + Tag.innerText = 'CREATOR' + if (Type === 'guilds') { Tag.innerText = 'LEADER' } + NameElement.appendChild(Tag) + + //new window.bootstrap.Tooltip(Tag, {toggle:"tooltip",title:"This user is the creator of this asset!"}) } } -}); -Observer.observe(Comments, {attributes: false, childList: true, subtree: false}) -function LoadCreatorTag(element) { - let NameElement; - if (!(Type === 'guilds')) { - NameElement = element.querySelector('.text-reset[href^="/users/"]') - } else { - NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]') - } - let UserID = NameElement.getAttribute('href').split('/')[2] - if (UserID === CreatorID) { - let Tag = document.createElement('span') - Tag.classList = 'badge bg-primary' - Tag.style.marginLeft = '5px' - Tag.style.verticalAlign = 'text-top' - Tag.innerText = 'CREATOR' - if (Type === 'guilds') { Tag.innerText = 'LEADER' } - NameElement.appendChild(Tag) - - //new window.bootstrap.Tooltip(Tag, {toggle:"tooltip",title:"This user is the creator of this asset!"}) - } -} \ No newline at end of file + Array.from(Comments.children).forEach(element => { + LoadCreatorTag(element) + }); +})(); \ No newline at end of file diff --git a/js/places/place-view.js b/js/places/place-view.js index 524cad5..1b5a6f5 100644 --- a/js/places/place-view.js +++ b/js/places/place-view.js @@ -8,7 +8,7 @@ var Settings; var PinnedGamesData = [] let GamePinned; -let InfoColumns = document.querySelectorAll('#main-content .col:has(#likes-data-container) .card:last-child ul') +let InfoColumns = document.querySelectorAll('#main-content .col:has(#likes-data-container) .card:has(.fas.fa-chart-bar) ul') let CalculateRevenueButton; const AchievementsTab = document.getElementById('achievements-tabpane') @@ -414,8 +414,12 @@ async function PlaceRevenue() { } /* + let AchievementCost = 0 + let FreeAchievements = null; for (let achievement of Achievements.achievements) { // decrease total by price of achievement creation based on when the achievement was created + + if () } */ @@ -430,54 +434,6 @@ async function PlaceRevenue() { function round5(number) { const remainder = number % 5; if (remainder < 2.5) { return number - remainder; } else { return number + (5 - remainder); } } -function ImprovedAchievements() { - const AchievementCount = Achievements.length - let AchievementsEarned = 0 - - for (let achievement of Achievements) { - Achieved = (achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined) - - if (Achieved === true) { - achievement.style.borderColor = 'gold' - AchievementsEarned++ - } - } - - const PercentageEarned = ((AchievementsEarned*100)/AchievementCount).toFixed(0) - - const ProgressBar = document.createElement('div') - ProgressBar.role = 'progressbar' - ProgressBar.classList = 'progress' - ProgressBar.style.background = '#000' - ProgressBar.ariaValueNow = PercentageEarned - ProgressBar.ariaValueMin = "0" - ProgressBar.ariaValueMax = "100" - ProgressBar.innerHTML = `
${PercentageEarned}%
` - - AchievementsTab.prepend(document.createElement('hr')) - AchievementsTab.prepend(ProgressBar) - - fetch('https://api.polytoria.com/v1/users/') - .then(response => { - if (!response.ok) { - throw new Error('Network not ok') - } - return response.json() - }) - .then(data => { - const UserCount = data.total - for (let achievement of Achievements) { - const OwnerText = achievement.getElementsByClassName('text-muted small my-0')[0] - // thanks to Stackoverflow on how to remove everything except numbers from string - const OwnerCount = parseInt(OwnerText.innerText.replace(/[^0-9]/g, '')) - const PercentageOfPlayers = ((OwnerCount*100)/UserCount).toFixed(2) - - OwnerText.innerHTML += " (" + PercentageOfPlayers + "%)" - } - }) - .catch(error => {console.log(error)}); -} - function AchievementProgressBar() { const AchievementCount = Achievements.length let AchievementsEarned = 0 @@ -506,7 +462,7 @@ function AchievementProgressBar() { } function AchievementEarnedPercentage() { - fetch('https://api.polytoria.com/v1/users/') + fetch('https://api.polytoria.com/v1/places/' + PlaceID) .then(response => { if (!response.ok) { throw new Error('Network not ok') @@ -514,15 +470,37 @@ function AchievementEarnedPercentage() { return response.json() }) .then(data => { - const UserCount = data.total + const UserCount = data.uniqueVisits for (let achievement of Achievements) { const OwnerText = achievement.getElementsByClassName('text-muted small my-0')[0] // thanks to Stackoverflow on how to remove everything except numbers from string const OwnerCount = parseInt(OwnerText.innerText.replace(/[^0-9]/g, '')) const PercentageOfPlayers = ((OwnerCount*100)/UserCount).toFixed(2) - OwnerText.innerHTML += " (" + PercentageOfPlayers + "%)" + OwnerText.innerHTML += " (" + PercentageOfPlayers + "%, " + GetAchievementDifficulty(PercentageOfPlayers) + ")" } }) .catch(error => {console.log(error)}); +} + +function GetAchievementDifficulty(percent) { + if (percent >= 90 && percent <= 100) { + return 'Freebie' + } else if (percent >= 80 && percent <= 89.9) { + return 'Cake Walk' + } else if (percent >= 50 && percent <= 79.9) { + return 'Easy' + } else if (percent >= 30 && percent <= 49.9) { + return 'Moderate' + } else if (percent >= 20 && percent <= 29.9) { + return 'Challenging' + } else if (percent >= 10 && percent <= 19.9) { + return 'Hard' + } else if (percent >= 5 && percent <= 9.9) { + return 'Extreme' + } else if (percent >= 1 && percent <= 4.9) { + return 'Insane' + } else if (percent >= 0 && percent <= 0.9) { + return 'Impossible' + } } \ No newline at end of file diff --git a/js/settings.js b/js/settings.js index 5c0f316..781554c 100755 --- a/js/settings.js +++ b/js/settings.js @@ -1,5 +1,5 @@ const SettingsURL = chrome.runtime.getURL('settings.html') -const InExtensionSettings = (window.location.pathname.split('/')[3] === "polyplus") +const InExtensionSettings = (window.location.pathname.split('/')[3] === "polyplus" && window.location.hash !== "#dev") if (InExtensionSettings === true) { window.location.href = SettingsURL + window.location.hash } diff --git a/js/store/item-view.js b/js/store/item-view.js index 62d1ba8..c0d7510 100755 --- a/js/store/item-view.js +++ b/js/store/item-view.js @@ -1,28 +1,16 @@ const ItemID = window.location.pathname.split('/')[2] const ItemType = document.querySelector('.row .badge').innerHTML -const MeshTypes = [ - "hat", - "hair", - "head attachment", - "face accessory", - "neck accessory", - "head cover", - "back accessory", - "shoulder accessory", - "tool" -] - -var Utilities; var Settings; var ItemWishlist; var PurchaseBtn; var WishlistBtn; var ItemOwned; +var InitialOwners; + +var Utilities; (async () => { - if (!(window.location.href.split('/')[4]) || ItemType === "achievement") {return} - Utilities = await import(chrome.runtime.getURL('resources/utils.js')); Utilities = Utilities.default @@ -43,23 +31,21 @@ var ItemOwned; HandleItemWishlist() } - if (Settings.TryOnItemsOn === true) { + if (Settings.TryOnItemsOn === true && (Utilities.MeshTypes.indexOf(ItemType.toLowerCase()) !== -1 || Utilities.TextureTypes.indexOf(ItemType.toLowerCase()) !== -1)) { 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 + InitialOwners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json()) Sales.children[0].innerText = 'Owners' - Sales.children[1].innerText = Owners.toLocaleString() + Sales.children[1].innerText = Owners.total.toLocaleString() } } - - if (new URLSearchParams(window.location.search).get('hoardersList') === 'true') { - HoardersList(1) - } else if ((Settings.HoardersListOn === true && document.getElementById('resellers') !== null)) { + + if ((Settings.HoardersListOn === true && document.getElementById('resellers') !== null)) { HoardersList(2) } }) @@ -78,13 +64,13 @@ chrome.storage.onChanged.addListener(function(changes, namespace) { } else { if (!(ItemWishlist.length === 25)) { WishlistBtn.removeAttribute('disabled') - WishlistBtn.classList = 'btn btn-primary btn-sm' + WishlistBtn.classList = 'btn btn-warning btn-sm' WishlistBtn.innerHTML = ` Wishlist Item ` } else { WishlistBtn.setAttribute('disabled', true) - WishlistBtn.classList = 'btn btn-primary btn-sm' + WishlistBtn.classList = 'btn btn-warning btn-sm' WishlistBtn.innerHTML = ` Wishlist Item ` @@ -96,6 +82,7 @@ chrome.storage.onChanged.addListener(function(changes, namespace) { async function IRLPrice() { const Price = PurchaseBtn.getAttribute('data-price') + if (Price === null || Price === "0") { return } const Span = document.createElement('span') Span.classList = 'text-muted polyplus-own-tag' Span.style.fontSize = '0.7rem' @@ -131,7 +118,7 @@ function HandleItemWishlist() { Un-Wishlist Item ` } else { - WishlistBtn.classList = 'btn btn-primary btn-sm' + WishlistBtn.classList = 'btn btn-warning btn-sm' WishlistBtn.innerHTML = ` Wishlist Item ` @@ -145,7 +132,7 @@ function HandleItemWishlist() { let i = ItemWishlist.indexOf(parseInt(ItemID)) if (i !== -1) { ItemWishlist.splice(i, 1) - WishlistBtn.classList = 'btn btn-primary btn-sm' + WishlistBtn.classList = 'btn btn-warning btn-sm' WishlistBtn.innerHTML = ` Wishlist Item ` @@ -171,6 +158,7 @@ function HandleItemWishlist() { } function TryOnItems() { + console.log(Utilities, Utilities.MeshTypes, Utilities.TextureTypes) const Avatar = { "useCharacter": true, "items": [], @@ -194,33 +182,14 @@ function TryOnItems() { const TryOnBtn = document.createElement('button') TryOnBtn.classList = 'btn btn-outline-warning' TryOnBtn.style = 'position: absolute; bottom: 60px; right: 10px;' + if (document.getElementsByClassName('3dviewtoggler')[0] === undefined) { + TryOnBtn.style.bottom = '15px;' + } TryOnBtn.setAttribute('data-bs-toggle', 'tooltip') TryOnBtn.setAttribute('data-bs-title', 'Try this item on your avatar') 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 this avatar on your avatar before purchasing it! -
- - ` - - document.body.prepend(TryOnModal) - ItemThumbnail.parentElement.appendChild(TryOnBtn) - TryOnModal.children[1].prepend(TryIFrame) - - Utilities.InjectResource('registerTooltips') - - fetch("https://api.polytoria.com/v1/users/:id/avatar".replace(':id', JSON.parse(window.localStorage.getItem('account_info')).ID)) + fetch("https://api.polytoria.com/v1/users/" + JSON.parse(window.localStorage.getItem('account_info')).ID + "/avatar") .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); @@ -255,7 +224,7 @@ function TryOnItems() { Avatar.leftLegColor = "#" + data.colors.leftLeg Avatar.rightLegColor = "#" + data.colors.rightLeg - if (MeshTypes.indexOf(AssetType.toLowerCase()) !== -1) { + if (Utilities.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) { @@ -276,7 +245,7 @@ function TryOnItems() { .catch(error => { console.error('Fetch error:', error); }); - } else { + } else if (Utilities.TextureTypes.indexOf(AssetType.toLowerCase()) !== -1) { fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', window.location.pathname.split('/')[2])) .then(response => { if (!response.ok) { @@ -286,13 +255,16 @@ function TryOnItems() { }) .then(data => { switch (AssetType) { - case 'shirt': + case 'Shirt': + console.log('IS SHIRT') Avatar.shirt = data.url break - case 'pants': + case 'Pants': + console.log('IS PANTS') Avatar.pants = data.url break - case 'face': + case 'Face': + console.log('IS FACE') Avatar.face = data.url break } @@ -307,82 +279,249 @@ function TryOnItems() { .catch(error => { console.error('Fetch error:', error); }); + + 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 this avatar on your avatar before purchasing it! +
+
+ +
+
+ + ` + + document.body.prepend(TryOnModal) + ItemThumbnail.parentElement.appendChild(TryOnBtn) + TryOnModal.children[1].prepend(TryIFrame) + + Utilities.InjectResource('registerTooltips') } async function HoardersList(min) { let Page = 0 - let Tabs = null - if (new URLSearchParams(window.location.search).get('hoardersList') !== 'true') { - Tabs = document.getElementById('store-tabs') - } - const Owners = [] - const InitialOwners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json()) - Owners.push(...InitialOwners.inventories) - if (InitialOwners.pages > 1) { - if (InitialOwners.pages > 3) {InitialOwners.pages = 3} - for (let i = 1; i < InitialOwners.pages; i++) { - console.log(i) - const PageResult = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100&page=' + (i+1))).json()).inventories - console.log(PageResult) - Owners.push(...PageResult) + let Tabs = document.getElementById('store-tabs') + + const Tab = document.createElement('li') + Tab.classList = 'nav-item' + Tab.innerHTML = ` + + + Hoarders + + ` + Tabs.appendChild(Tab) + + const TabContent = document.createElement('div') + TabContent.classList = 'd-none' + TabContent.innerHTML = ` + + loading... (this may take a few seconds) + + + ` + document.getElementById('owners').parentElement.appendChild(TabContent) + + // Add tab logic + Array.from(Tabs.children).forEach(tab => { + tab.addEventListener('click', function() { + if (tab === Tab) { + Array.from(Tabs.children).forEach(tab => {tab.children[0].classList.remove('active')}) + Array.from(document.getElementById('owners').parentElement.children).forEach(tab => {tab.classList.add('d-none')}) + tab.children[0].classList.add('active') + TabContent.classList.remove('d-none') + } + }) + }) + + Tab.addEventListener('click', async function(){ + const Owners = [] + if (InitialOwners === undefined) { + InitialOwners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json()) } - } - const Formatted = {} - - for (let owner of Owners) { - if (Formatted[owner.user.id] !== undefined) { - Formatted[owner.user.id].copies++ - Formatted[owner.user.id].serials.push(owner.serial) - } else { - Formatted[owner.user.id] = { - user: owner.user, - copies: 1, - serials: [owner.serial] + Owners.push(...InitialOwners.inventories) + + // Get owners (up to 300, if needed) + if (InitialOwners.pages > 1) { + if (InitialOwners.pages > 3) {InitialOwners.pages = 3} + for (let i = 1; i < InitialOwners.pages; i++) { + const PageResult = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100&page=' + (i+1))).json()).inventories + console.log(PageResult) + Owners.push(...PageResult) } } - } - - const Hoarders = new Promise(async (resolve, reject) => { - const Sorted = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies) - for (let hoarder of Sorted) { - const Avatar = (await (await fetch('https://api.polytoria.com/v1/users/' + hoarder.user.id)).json()).thumbnail.icon; - hoarder.user.avatar = Avatar; - if (Sorted.indexOf(hoarder) === Sorted.length-1) { resolve(Sorted) } - } - }) - Hoarders.then(async (hoarders) => { - const AmountOfHoarders = hoarders.length - const Groups = [] - - while (hoarders.length > 0) { - Groups.push(hoarders.splice(0, 4)) - } - if (min === 1) { - console.log('HOARDER LIST: ', Groups) - return + const Formatted = {} + + // Count copies & store serials of owners + for (let owner of Owners) { + if (Formatted[owner.user.id] !== undefined) { + Formatted[owner.user.id].copies++ + Formatted[owner.user.id].serials.push(owner.serial) + } else { + Formatted[owner.user.id] = { + user: owner.user, + copies: 1, + serials: [owner.serial] + } + } } - const Tab = document.createElement('li') - Tab.classList = 'nav-item' - Tab.innerHTML = ` - - - Hoarders (${AmountOfHoarders}) - - ` - Tabs.appendChild(Tab) + let Hoarders = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies) + let AmountOfHoarders = Hoarders.length + + // Break hoarders into groups of 4 + let Groups = [] + while (Hoarders.length > 0) { + Groups.push(Hoarders.splice(0, 4)) + } - const TabContent = document.createElement('div') - TabContent.classList = 'd-none' TabContent.innerHTML = ` -
+
${ Groups[Page].map((x) => `
-
- ${x.user.username} +
+
+
+ ${x.user.username} +
+ ${x.copies} Copies +
+ +
+
+
+ `).join('') + } +
+ + ` + Utilities.InjectResource('registerTooltips') + + const Container = document.getElementById('p+hoarders-container') + + // Pagination is annoying + const First = document.getElementById('p+hoarders-first-pg') + const Prev = document.getElementById('p+hoarders-prev-pg') + const Current = document.getElementById('p+hoarders-current-pg') + const Next = document.getElementById('p+hoarders-next-pg') + const Last = document.getElementById('p+hoarders-last-pg') + + const MinCopies = document.getElementById('p+hoarders-min-copies') + + if (Page > 0) { + Prev.parentElement.classList.remove('disabled') + First.parentElement.classList.remove('disabled') + } else { + Prev.parentElement.classList.add('disabled') + First.parentElement.classList.add('disabled') + } + if (Page < Groups.length-1) { + Next.parentElement.classList.remove('disabled') + Last.parentElement.classList.remove('disabled') + } else { + Next.parentElement.classList.add('disabled') + Last.parentElement.classList.add('disabled') + } + + First.addEventListener('click', function() { + if (Page > 0) { + Page = 0 + UpdateHoardersList() + } + }) + + Prev.addEventListener('click', function() { + if (Page > 0) { + Page-- + UpdateHoardersList() + } + }) + + Next.addEventListener('click', function() { + if (Page < Groups.length-1) { + Page++ + UpdateHoardersList() + } + }) + + Last.addEventListener('click', function() { + if (Page < Groups.length-1) { + Page = Groups.length-1 + UpdateHoardersList() + } + }) + + MinCopies.addEventListener('change', function(){ + Page = 0 + min = parseInt(MinCopies.options[MinCopies.selectedIndex].value) + console.log(min) + Hoarders = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies) + AmountOfHoarders = Hoarders.length + Groups = [] + while (Hoarders.length > 0) { + Groups.push(Hoarders.splice(0, 4)) + } + UpdateHoardersList() + }) + + const UpdateHoardersList = function() { + console.log(Hoarders, AmountOfHoarders, Groups) + Current.innerText = Page+1 + Container.innerHTML = Groups[Page].map((x) => ` +
+
+
@@ -401,148 +540,23 @@ async function HoardersList(min) {
`).join('') - } -
- - ` - document.getElementById('owners').parentElement.appendChild(TabContent) - Utilities.InjectResource('registerTooltips') + Utilities.InjectResource('registerTooltips') - Array.from(Tabs.children).forEach(tab => { - tab.addEventListener('click', function() { - if (tab === Tab) { - Array.from(Tabs.children).forEach(tab => {tab.children[0].classList.remove('active')}) - Array.from(document.getElementById('owners').parentElement.children).forEach(tab => {tab.classList.add('d-none')}) - tab.children[0].classList.add('active') - TabContent.classList.remove('d-none') - } - }) - }) - - const Container = document.getElementById('hoarders-container') - - const Prev = document.getElementById('hoarders-prev-pg') - const Current = document.getElementById('hoarders-current-pg') - const Next = document.getElementById('hoarders-next-pg') - - if (Page > 0) { - Prev.parentElement.classList.remove('disabled') - } else { - Prev.parentElement.classList.add('disabled') - } - if (Page < Groups.length-1) { - Next.parentElement.classList.remove('disabled') - } else { - Next.parentElement.classList.add('disabled') - } - - Prev.addEventListener('click', function() { if (Page > 0) { - Page-- - Current.innerText = Page+1 - Container.innerHTML = Groups[Page].map((x) => ` -
-
-
-
- ${x.user.username} -
-
-
-
- ${x.user.username} -
- ${x.copies} Copies -
-
- -
-
-
- `).join('') - - Utilities.InjectResource('registerTooltips') - - if (Page > 0) { - Prev.parentElement.classList.remove('disabled') - } else { - Prev.parentElement.classList.add('disabled') - } - if (Page < Groups.length-1) { - Next.parentElement.classList.remove('disabled') - } else { - Next.parentElement.classList.add('disabled') - } + Prev.parentElement.classList.remove('disabled') + First.parentElement.classList.remove('disabled') + } else { + Prev.parentElement.classList.add('disabled') + First.parentElement.classList.add('disabled') } - }) - - Next.addEventListener('click', function() { if (Page < Groups.length-1) { - Page++ - Current.innerText = Page+1 - Container.innerHTML = Groups[Page].map((x) => ` -
-
-
-
- ${x.user.username} -
-
-
-
- ${x.user.username} -
- ${x.copies} Copies -
-
- -
-
-
- `).join('') - - Utilities.InjectResource('registerTooltips') - - if (Page > 0) { - Prev.parentElement.classList.remove('disabled') - } else { - Prev.parentElement.classList.add('disabled') - } - if (Page < Groups.length-1) { - Next.parentElement.classList.remove('disabled') - } else { - Next.parentElement.classList.add('disabled') - } + Next.parentElement.classList.remove('disabled') + Last.parentElement.classList.remove('disabled') + } else { + Next.parentElement.classList.add('disabled') + Last.parentElement.classList.add('disabled') } - }) + } }) } \ No newline at end of file diff --git a/js/store/store.js b/js/store/store.js index 955d1ce..8efb97e 100755 --- a/js/store/store.js +++ b/js/store/store.js @@ -15,10 +15,6 @@ chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){ Utilities = await import(chrome.runtime.getURL('resources/utils.js')); Utilities = Utilities.default - Update() -}); - -async function Update() { if (Settings.IRLPriceWithCurrencyOn === true) { Array.from(ItemGrid.children).forEach(element => { LoadIRLPrices(element) @@ -33,22 +29,22 @@ async function Update() { } if (Settings.EventItemsCatOn === true) { - console.log('is event yay!!') EventItems() } -} +}); -let UpdateCount = 0 const observer = new MutationObserver(async function (list){ - UpdateCount++ - console.log(Settings.EventItemsCatOn, document.getElementById('event-items-pagination'), EventItemsShown, UpdateCount) if (Settings.EventItemsCatOn === true) { if (document.getElementById('event-items-pagination') === null) { ItemGrid.classList.add('itemgrid') + ItemGrid.parentElement.classList.remove('col-lg-9') document.getElementById('pagination').style.display = 'block' - document.getElementById('storecat-eventitems').checked = false + if (document.getElementById('storecat-eventitems') !== null) { + document.getElementById('storecat-eventitems').checked = false + } } else { ItemGrid.classList.remove('itemgrid') + ItemGrid.parentElement.classList.add('col-lg-9') document.getElementById('pagination').style.display = 'none' } } @@ -139,7 +135,7 @@ function EventItems() { Object.values(EventData.eventDetails).forEach((x, index) => {Events.push({ ...x, - items: EventData.items.filter((x) => x.event === Object.keys(EventData.eventDetails)[index]) + items: EventData.items.filter((x) => x.event === Object.keys(EventData.eventDetails)[index]).sort((a, b) => a.id - b.id) })}) while (Events.length > 0) { Groups.push(Events.splice(0, 5)) @@ -156,6 +152,14 @@ function EventItems() {
${x.date}
${x.name}
+ ${ (x.link !== undefined) ? ` + + ` : '' }
@@ -211,22 +215,33 @@ function EventItems() { const Container = document.getElementById('p+ei') const Pagination = document.getElementById('event-items-pagination') - //const First = document.getElementById('p+ei-pagination-first') + const First = document.getElementById('p+ei-pagination-first') const Prev = document.getElementById('p+ei-pagination-prev') const Current = document.getElementById('p+ei-pagination-current') const Next = document.getElementById('p+ei-pagination-next') - //const Last = document.getElementById('p+ei-pagination-last') + const Last = document.getElementById('p+ei-pagination-last') if (Page > 0) { Prev.parentElement.classList.remove('disabled') + First.parentElement.classList.remove('disabled') } else { Prev.parentElement.classList.add('disabled') + First.parentElement.classList.add('disabled') } if (Page < Groups.length-1) { Next.parentElement.classList.remove('disabled') + Last.parentElement.classList.remove('disabled') } else { Next.parentElement.classList.add('disabled') + Last.parentElement.classList.add('disabled') } + + First.addEventListener('click', function() { + if (Page > 0) { + Page = 0 + UpdateEventItems() + } + }) Prev.addEventListener('click', function() { if (Page > 0) { @@ -242,6 +257,13 @@ function EventItems() { } }) + Last.addEventListener('click', function() { + if (Page < Groups.length-1) { + Page = Groups.length-1 + UpdateEventItems() + } + }) + const UpdateEventItems = function() { Current.innerText = Page+1 Container.innerHTML = Groups[Page].map((x, index) => ` @@ -278,13 +300,17 @@ function EventItems() { if (Page > 0) { Prev.parentElement.classList.remove('disabled') + First.parentElement.classList.remove('disabled') } else { Prev.parentElement.classList.add('disabled') + First.parentElement.classList.add('disabled') } if (Page < Groups.length-1) { Next.parentElement.classList.remove('disabled') + Last.parentElement.classList.remove('disabled') } else { Next.parentElement.classList.add('disabled') + Last.parentElement.classList.add('disabled') } } }) diff --git a/manifest.json b/manifest.json index 8aba014..dfaeb9d 100755 --- a/manifest.json +++ b/manifest.json @@ -3,10 +3,9 @@ "author": "Index", "name": "Poly+", "version": "1.11", - "version_name": "Pre-Release Build (stable: v1.1.1)", + "version_name": "Pre-Release Build (v1.1.1)", "description": "Power-up your Polytoria experience with Poly+! Created by Index.", "homepage_url": "https://polyplus.vercel.app/", - "download_url": "https://github.com/indexxing/PolyPlus/releases", "permissions": ["storage", "contextMenus", "tabs", "scripting", "alarms", "notifications"], "content_scripts": [ { @@ -29,7 +28,7 @@ }, { - "matches": ["https://polytoria.com/my/settings/polyplus-debug/*"], + "matches": ["https://polytoria.com/my/settings/polyplus#dev"], "js": ["/js/debug.js"] }, @@ -38,11 +37,6 @@ "js": ["/js/places/place-view.js"] }, - { - "matches": ["https://polytoria.com/join-place/**"], - "js": ["/js/places/place-join.js"] - }, - { "matches": ["https://polytoria.com/create/place/**"], "js": ["/js/places/place-edit.js"] @@ -54,7 +48,7 @@ }, { - "matches": ["https://polytoria.com/users/**"], + "matches": ["https://polytoria.com/u/**"], "js": ["/js/account/profile.js"] }, @@ -105,7 +99,7 @@ }, { - "matches": ["https://polytoria.com/my/avatar?sandbox=true"], + "matches": ["https://polytoria.com/my/avatar*"], "js": ["/js/account/avatar-sandbox2.js"] }, diff --git a/resources/avatar-sandbox.html b/resources/avatar-sandbox.html index 2a3569c..3aa32ba 100755 --- a/resources/avatar-sandbox.html +++ b/resources/avatar-sandbox.html @@ -23,7 +23,7 @@
- Avatar + Avatar Sandbox
@@ -64,7 +64,7 @@
-
+
Body Colors @@ -83,6 +83,7 @@
+ feature of Poly+