From 792375158d4b7d33bbcb2f646053e4621394804a Mon Sep 17 00:00:00 2001 From: Index Date: Wed, 10 Jul 2024 07:40:26 -0500 Subject: [PATCH] feat: add avatar sandbox oufits feature! --- js/account/avatar-sandbox.js | 354 ++++++++++++++++++++++++++++------ resources/avatar-sandbox.html | 46 +++++ 2 files changed, 340 insertions(+), 60 deletions(-) diff --git a/js/account/avatar-sandbox.js b/js/account/avatar-sandbox.js index 42f88f2..4b04755 100644 --- a/js/account/avatar-sandbox.js +++ b/js/account/avatar-sandbox.js @@ -70,6 +70,7 @@ let Order = "desc" let ShowOffsale = true let TabSelected = "hat" let RetroItems = null +let Outfits = null /* Customization */ let SelectedBodyPart @@ -78,8 +79,9 @@ let SelectedBodyPart Utilities = await import(chrome.runtime.getURL('resources/utils.js')); Utilities = Utilities.default; - chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ + chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_AvatarSandboxOutfits'], function(result){ Settings = result.PolyPlus_Settings || Utilities.DefaultSettings; + Outfits = result.PolyPlus_AvatarSandboxOutfits || []; if (Settings.AvatarSandboxOn || 1 === 1) { if (new URLSearchParams(window.location.search).has('sandbox')) { @@ -284,6 +286,44 @@ async function PageLoad() { } }) + const SaveButton = document.getElementById('saveOutfit') + const OutfitCreateModal = document.getElementById('p+outfit_create') + const OutfitCreateButton = document.getElementById('p+save_outfit_confirm') + const OutfitCreateError = document.getElementById('p+outfit_create_error') + SaveButton.addEventListener('click', function(){ + console.log(Outfits) + OutfitCreateModal.showModal() + }) + + OutfitCreateButton.addEventListener('click', function(){ + let OutfitName = OutfitCreateButton.previousElementSibling.value.trim() + OutfitCreateButton.previousElementSibling.value = '' + if (OutfitName === '') { + OutfitCreateError.classList = 'text-danger'; + OutfitCreateError.innerHTML = ' You cannot name an outfit nothing.'; + return + } else if (OutfitName.length > 25) { + OutfitName = OutfitName.substring(0, 25) + } else if (Outfits.findIndex((x) => x.name.trim() === OutfitName) !== -1) { + OutfitCreateError.classList = 'text-danger'; + OutfitCreateError.innerHTML = ' You already have an outfit with the name "' + OutfitName + '".'; + return + } + OutfitCreateModal.close() + Outfits.push({ + name: OutfitName, + createdAt: new Date().getTime(), + data: Avatar + }) + if (TabSelected === 'outfit') { + LoadItems() + } + + chrome.storage.sync.set({'PolyPlus_AvatarSandboxOutfits': Outfits}, function(){ + console.log('Saved outfits!') + }) + }) + document.getElementById('view-cache').addEventListener('click', function(){ console.log('Cache: ', ItemCache) }) @@ -486,9 +526,21 @@ async function LoadItems() { document.getElementById('inventory').innerHTML = '' let Items; - if (TabSelected !== 'retro') { + if (['retro', 'outfit'].indexOf(TabSelected) === -1) { Items = (await (await fetch('https://api.polytoria.com/v1/store?limit=12&order=' + Order + '&sort=' + Sort + '&showOffsale=' + ShowOffsale + '&types[]='+ TabSelected +'&search=' + Search + '&page=' + Page)).json()) - } else { + } else if (TabSelected === 'outfit') { + const OutfitsClone = structuredClone(Outfits) + let Groups = [] + while (OutfitsClone.length > 0) { + Groups.push(OutfitsClone.splice(0, 12)); + } + + console.log(Groups, OutfitsClone) + Items = { + assets: Groups[Page - 1], + pages: Groups.length + } + } else if (TabSelected === 'retro') { if (RetroItems === null) { Items = (await (await fetch('https://poly-upd-archival.pages.dev/data.json')).json()) Object.values(Items).forEach((item, index) => { @@ -538,65 +590,239 @@ async function LoadItems() { document.getElementById('pagination-first').classList.add('disabled'); } document.getElementById('pagination-current').innerText = Page - Items.assets.forEach(item => { - const ItemColumn = document.createElement('div') - ItemColumn.classList = 'col-auto' - ItemColumn.innerHTML = ` -
-
-
- - ${ (item.type === 'hat') ? ` - - ${CleanAccessoryType(item.accessoryType)} - - ` : ''} - + + if (Items.assets === undefined) { Items.assets = [] } + if (Items.assets.length > 0) { + document.getElementById('inventory').classList.add('itemgrid') + if (TabSelected !== 'outfit') { + Items.assets.forEach(item => { + const ItemColumn = document.createElement('div') + ItemColumn.classList = 'col-auto' + ItemColumn.innerHTML = ` +
+
+
+ + ${ (item.type === 'hat') ? ` + + ${CleanAccessoryType(item.accessoryType)} + + ` : ''} + +
+
+ +
${item.name}
+
+ + by ${ (["hat", "tool", "face", "torso"].indexOf(item.type) !== -1) ? 'Polytoria' : item.creator.name } + + -
${item.name}
- - - by ${ (["hat", "tool", "face", "torso"].indexOf(item.type) !== -1) ? 'Polytoria' : item.creator.name } - - { + const ItemColumn = document.createElement('div') + ItemColumn.classList = 'col-auto' + ItemColumn.innerHTML = ` +
+
+
+
+ +
+
+ + + +
+ + +
+
+
${outfit.name}
+
+ +
+ + +
+
+
+ ` + document.getElementById('inventory').appendChild(ItemColumn) + Utilities.InjectResource("registerTooltips") - if (item.type === 'hat') { - ItemCache[item.id].accessoryType = item.accessoryType - } + ItemColumn.getElementsByClassName('p+outfit_wear_button')[0].addEventListener('click', function(){ + if (Avatar === outfit.data) { + return + } + console.log('Equipped Outfit: ', outfit) + Avatar = outfit.data + UpdateAvatar() + }) + + const OutfitRenameModal = document.getElementById('p+outfit_rename') + const OutfitRenameButton = document.getElementById('p+rename_outfit_confirm') + const OutfitRenameError = document.getElementById('p+outfit_rename_error') + ItemColumn.getElementsByClassName('p+outfit_rename_button')[0].addEventListener('click', function(){ + OutfitRenameModal.showModal() + document.getElementById('p+outfit_rename_name').innerText = outfit.name + }) + + OutfitRenameButton.addEventListener('click', function(){ + let OutfitName = OutfitRenameButton.previousElementSibling.value.trim() + OutfitRenameButton.previousElementSibling.value = '' + if (OutfitName === '') { + OutfitRenameError.classList = 'text-danger'; + OutfitRenameError.innerHTML = ' You cannot name an outfit nothing.'; + return + } else if (OutfitName.length > 25) { + OutfitName = OutfitName.substring(0, 25) + } else if (Outfits.findIndex((x) => x.name.trim() === OutfitName) !== -1) { + OutfitRenameError.classList = 'text-danger'; + OutfitRenameError.innerHTML = ' You already have an outfit with the name "' + OutfitName + '".'; + return + } + OutfitRenameModal.close() + Outfits[index].name = OutfitName + if (TabSelected === 'outfit') { + LoadItems() + } + + chrome.storage.sync.set({'PolyPlus_AvatarSandboxOutfits': Outfits}, function(){ + console.log('Saved outfits!') + }) + }) + + let OverwritePending = false + const OutfitOverwriteButton = ItemColumn.getElementsByClassName('p+outfit_overwrite_button')[0] + OutfitOverwriteButton.addEventListener('click', function(e){ + e.stopPropagation() + if (OverwritePending === false) { + OverwritePending = true + OutfitOverwriteButton.children[1].innerText = 'Are you sure?' + setTimeout(function (){ + if (OverwritePending === true) { + OutfitOverwriteButton.children[1].innerText = 'Overwrite' + OverwritePending = false + } + }, 3000) + } else { + OverwritePending = false + console.log('Overwrite Outfit (outfit, avatar): ', outfit, Avatar) + + Outfits[index].data = Avatar + if (TabSelected === 'outfit') { + LoadItems() + } + + chrome.storage.sync.set({'PolyPlus_AvatarSandboxOutfits': Outfits}, function(){ + console.log('Saved outfits!') + }) + } + }) + + let DeletePending = false + const OutfitDeleteButton = ItemColumn.getElementsByClassName('p+outfit_delete_button')[0] + OutfitDeleteButton.addEventListener('click', function(e){ + e.stopPropagation() + if (DeletePending === false) { + DeletePending = true + OutfitDeleteButton.children[1].innerText = 'Are you sure?' + setTimeout(function (){ + if (DeletePending === true) { + OutfitDeleteButton.children[1].innerText = 'Delete' + DeletePending = false + } + }, 3000) + } else { + DeletePending = false + console.log('Deleted Outfit: ', outfit) + + Outfits.splice(index, 1) + if (TabSelected === 'outfit') { + LoadItems() + } + + chrome.storage.sync.set({'PolyPlus_AvatarSandboxOutfits': Outfits}, function(){ + console.log('Saved outfits!') + }) + } + }) + }) } - - ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){ - WearAsset(item, item.id) - }) - }) + } else { + document.getElementById('inventory').classList.remove('itemgrid') + document.getElementById('inventory').innerHTML = ` +
+

+ +

+
+ You do not have any items matching this type or search query. Find new items in the store! +
+
+ ` + } } function LoadWearing() { @@ -710,5 +936,13 @@ function FormatPrice(price) { } else { return 'text-muted">???
' } - return "what" -} \ No newline at end of file + return '">how did this happen
' +} + +chrome.storage.onChanged.addListener(function (changes, namespace) { + if ('PolyPlus_AvatarSandboxOutfits' in changes) { + chrome.storage.sync.get(['PolyPlus_AvatarSandboxOutfits'], function (result) { + Outfits = result.PolyPlus_AvatarSandboxOutfits || []; + }); + } +}) \ No newline at end of file diff --git a/resources/avatar-sandbox.html b/resources/avatar-sandbox.html index 4858e69..a841ff3 100755 --- a/resources/avatar-sandbox.html +++ b/resources/avatar-sandbox.html @@ -34,6 +34,10 @@ #options *:not(input):not(:nth-child(2)) { margin-bottom: 3.5px; } + + [class^="p+outfit_overwrite_button"]:hover, [class^="p+outfit_delete_button"]:hover { + cursor: pointer; + }
@@ -112,6 +116,42 @@
+ +
+
+
Create Outfit
+ Save this avatar for later! +
+
+ +
+
+ +
+ +
+
+
Rename Outfit
+ Renaming Outfit "none" +
+
+ +
+
+ +
Poly+

Avatar Sandbox @@ -260,6 +300,12 @@ Retro +