diff --git a/css/settings.css b/css/settings.css new file mode 100644 index 0000000..53c126b --- /dev/null +++ b/css/settings.css @@ -0,0 +1,176 @@ +html, +body, +#page { + background: #202020; + color: #fff; +} + +#page { + margin-top: 7.5rem; + width: 65%; + margin-right: auto; + margin-left: auto; + margin-bottom: 3.5rem; +} + +h1 { + font-size: 4.6rem; + /*color: rgb(48, 48, 48);*/ +} + +h1 span.indent { + border-left: 10px solid rgb(48, 48, 48); + margin-right: 15px; +} + +h1 span.highlight { + color: red; +} + +h2 { + color: rgb(48, 48, 48); +} + +h2 span.indent { + border-left: 7.5px solid rgb(48, 48, 48); + margin-right: 15px; +} + +.setting-container:not(:last-child) { + margin-bottom: 20px; +} + +.setting-container .title { + font-size: 1.4rem; + font-weight: lighter; +} + +.setting-container .desc { + color: rgb(120, 120, 120); +} + +.goback { + color: rgb(120, 120, 120); + text-decoration: none; +} + +dialog { + background-color: #080808; + color: #c4c4c4; + border: 1px solid #3bafff; + border-radius: 10px; +} + +.input-group-text { + background-color: #000; + border-color: #000; + color: #fff; +} + +label { + font-size: 0.8rem; + margin-bottom: 2.75px; +} + +dialog::backdrop { + background-color: rgba(0, 0, 0, 0.73); +} + +dialog .modal-header p { + margin-bottom: 0px; + color: #fff; +} + +dialog .modal-body p:first-child { + font-size: 0.9rem; +} + +.setting-container .indicator { + border-radius: 5rem; + display: inline-block; + cursor: default; +} + +.setting-container.enabled .indicator { + background-color: #007bff; +} + +.setting-container.disabled .indicator { + background-color: orangered; +} + +.toggle-btn { + float: right; + width: 100px; +} + +.limited-time { + background: transparent; + border-color: transparent; + box-shadow: -3px -3px 15px 0 rgba(255, 116, 16, 0.25) inset, 3px 3px 15px 0 rgba(205, 96, 255, 0.25) inset; +} + +.limited-time * { + position: relative; + z-index: 2; +} + +.limited-time .row { + --bs-gutter-x: 10px; +} + +.limited-time .indicator { + height: 100%; +} + +.limited-time .desc { + margin-bottom: 10px; + width: 85%; +} + +.limited-time-tag { + font-size: 0.7rem; + color: rgba(255, 116, 16, 0.25); + + -webkit-animation: LimitedTimeTag 5s ease infinite alternate; + -moz-animation: LimitedTimeTag 5s ease infinite alternate; + animation: LimitedTimeTag 5s ease infinite alternate; +} + +.limited-time::before { + content: ''; + position: absolute; + inset: 0; + padding: 3px; + background: + linear-gradient( + 45deg, + rgba(255, 116, 16, 1), + rgba(205, 96, 255, 1) + ); + -webkit-mask: + linear-gradient(#fff 0 0) content-box, + linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + display: block; + border-radius: inherit; +} + +@-webkit-keyframes LimitedTimeTag { + 0%{color:rgba(255, 116, 16, 1);} + 50%{color:rgba(23, 107, 233, 1);} + 100%{color:rgba(205, 96, 255, 1);} +} + +@-moz-keyframes LimitedTimeTag { + 0%{color:rgba(255, 116, 16, 1);} + 50%{color:rgba(23, 107, 233, 1);} + 100%{color:rgba(205, 96, 255, 1);} +} + +@keyframes LimitedTimeTag { + 0%{color:rgba(255, 116, 16, 1);} + 50%{color:rgba(23, 107, 233, 1);} + 100%{color:rgba(205, 96, 255, 1);} +} \ No newline at end of file diff --git a/css/specific.css b/css/specific.css index 663fa0c..420cb0b 100755 --- a/css/specific.css +++ b/css/specific.css @@ -20,6 +20,10 @@ body[data-URL^='/create/'] .col.d-flex.align-content-between.flex-wrap { text-overflow: ellipsis !important; } +#servers-tabpane .card { + margin-bottom: 10px; +} + /* ------------------------------------------ */ /* @@ -56,3 +60,35 @@ body:has(.polyplus-modal[open]) { } /* ------------------------------------------ */ + + +/* + EVENT PLACE CARD HIGHLIGHT ANIMATION + CSS BY @Dragonism ON POLYTORIA +*/ + +.event-card { + background-size: 200% 200% !important; + + -webkit-animation: EventPlace 5s ease infinite; + -moz-animation: EventPlace 5s ease infinite; + animation: EventPlace 5s ease infinite; +} + +@-webkit-keyframes EventPlace { + 0%{background-position:10% 0%} + 50%{background-position:91% 100%} + 100%{background-position:10% 0%} +} + +@-moz-keyframes EventPlace { + 0%{background-position:10% 0%} + 50%{background-position:91% 100%} + 100%{background-position:10% 0%} +} + +@keyframes EventPlace { + 0%{background-position:10% 0%} + 50%{background-position:91% 100%} + 100%{background-position:10% 0%} +} \ No newline at end of file diff --git a/js/account/home.js b/js/account/home.js index 44a6644..992247c 100755 --- a/js/account/home.js +++ b/js/account/home.js @@ -65,7 +65,7 @@ var FriendContainer = document.querySelector('.card:has(.friendsPopup) .card-bod let NewContainer = document.createElement('div'); NewContainer.style.display = 'none'; -NewContainer.classList = 'card card-dash mcard'; +NewContainer.classList = 'card card-dash mcard mb-3'; NewContainer.style.animationDelay = '0.18s'; NewContainer.innerHTML = ContainerElement; @@ -87,7 +87,7 @@ FriendContainer.prepend(BestFriendsContainer); async function Update() { chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) { - PinnedGamesData = result.PolyPlus_PinnedGames || []; + PinnedGamesData = result.PolyPlus_PinnedGames.toSorted((a, b) => b - a) || []; if (Settings.PinnedGamesOn === true) { PinnedGames(); @@ -123,7 +123,7 @@ function PinnedGames() { NewTitle.style.display = ''; } - PinnedGamesData.forEach((element) => { + for (let element of PinnedGamesData) { fetch('https://api.polytoria.com/v1/places/' + element) .then((response) => response.json()) .then((data) => { @@ -148,7 +148,7 @@ function PinnedGames() { .catch((error) => { console.error('Error:', error); }); - }); + } } function BestFriends() { @@ -180,8 +180,13 @@ function BestFriends() { } var SecondaryColumn = document.getElementsByClassName('col-lg-8')[0]; -SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[0]); -SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]); +if (document.getElementsByClassName('home-event-container')[0] === undefined) { + SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[0]); + SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]); +} else { + SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[1]); + SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[1]); +} async function IRLPrice() { (async () => { diff --git a/js/account/outfit-overwrite.js b/js/account/outfit-overwrite.js new file mode 100644 index 0000000..e69de29 diff --git a/js/account/profile.js b/js/account/profile.js index 7eee982..fd4f4a9 100755 --- a/js/account/profile.js +++ b/js/account/profile.js @@ -6,6 +6,7 @@ var Settings; var BestFriends; let FavoriteBtn; let CalculateButton; +let AvatarIFrame; let Utilities; @@ -18,6 +19,34 @@ if (Username) { chrome.storage.sync.get(['PolyPlus_Settings'], function (result) { Settings = result.PolyPlus_Settings || {}; + const InfoColumns = document.getElementById('user-stats-card'); + const UserIDRow = document.createElement('div') + UserIDRow.classList = 'mb-1' + UserIDRow.innerHTML = ` + Player ID + + ${UserID} + + ` + InfoColumns.children[0].insertBefore(UserIDRow, InfoColumns.children[0].children[1]); + + const CopyButton = UserIDRow.getElementsByTagName('a')[0] + CopyButton.addEventListener('click', function(){ + navigator.clipboard + .writeText(UserID) + .then(() => { + CopyButton.classList.add('text-success') + CopyButton.children[0].classList = 'fa-duotone fa-circle-check' + CopyButton.children[0].style.marginLeft = '3px' + + setTimeout(() => { + CopyButton.classList.remove('text-success') + CopyButton.children[0].classList = 'fad fa-copy' + CopyButton.children[0].style.marginLeft = '5px' + }, 1500); + }) + }) + if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) { IRLPrice(); } @@ -49,10 +78,55 @@ if (Username) { } }); } + + /* + + + + */ + + AvatarIFrame = document.getElementById('user-avatar-card').getElementsByTagName('iframe')[0] + if (Settings.AvatarDimensionToggleOn === true || 1 === 1) { + const AvatarCard = document.getElementById('user-avatar-card') + const ToggleButton = document.createElement('button') + ToggleButton.classList = 'btn btn-primary btn-sm 3dviewtoggler isactive' + ToggleButton.style = 'position: absolute; right: 15px; margin: 10px;' + ToggleButton.innerHTML = '' + AvatarCard.children[0].insertBefore(ToggleButton, AvatarIFrame) + + ToggleButton.addEventListener('click', async function(){ + if (ToggleButton.children[0].classList.contains('fa-image')) { + if (document.getElementById('polyplus-2davatar')) { + AvatarIFrame.style.display = 'none' + document.getElementById('polyplus-2davatar').style.display = 'block' + ToggleButton.children[0].classList = 'toggleIcn fad fa-360-degrees' + } else { + const AvatarImage = document.createElement('img') + AvatarImage.id = 'polyplus-2davatar' + AvatarImage.width = AvatarIFrame.offsetWidth + AvatarImage.height = AvatarIFrame.offsetHeight + + const UserDetails = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID)).json()) + AvatarImage.src = UserDetails.thumbnail.avatar + + AvatarIFrame.style.display = 'none' + AvatarCard.children[0].insertBefore(AvatarImage, AvatarCard.getElementsByClassName('user-badges')[0]) + + ToggleButton.children[0].classList = 'toggleIcn fad fa-360-degrees' + } + } else { + document.getElementById('polyplus-2davatar').style.display = 'none' + AvatarIFrame.style.display = 'block' + ToggleButton.children[0].classList = 'toggleIcn fad fa-image' + } + }) + } }); })(); - const AvatarIFrame = document.querySelector('[src^="/ptstatic"]'); + if (AvatarIFrame === null) { + AvatarIFrame = document.getElementById('user-avatar-card').getElementsByTagName('iframe')[0] + } const DropdownMenu = document.getElementsByClassName('dropdown-menu dropdown-menu-right')[0]; const CopyItem = document.createElement('a'); diff --git a/js/background.js b/js/background.js index 3a2ede9..738f63e 100755 --- a/js/background.js +++ b/js/background.js @@ -78,9 +78,12 @@ const DefaultSettings = { Banners: true, Rectangles: true }, - UploadMultipleDecals: true + UploadMultipleDecals: true, + GD_ServerBalanceOn: true, + AvatarDimensionToggleOn: true } +// ON EXTENSION INSTALL / RELOAD chrome.runtime.onInstalled.addListener(() => { chrome.storage.sync.get(['PolyPlus_Settings'], function(result){ const MergedSettings = MergeObjects((result.PolyPlus_Settings || DefaultSettings), DefaultSettings) @@ -90,6 +93,23 @@ chrome.runtime.onInstalled.addListener(() => { }) }); +chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + if (request.action === 'reload') { + chrome.runtime.reload(); + } else if (request.action === 'sweetalert2') { + chrome.tabs.query({ active: true, currentWindow: true }, function(tabs){ + console.log([request.icon, request.title, request.text]) + chrome.scripting + .executeScript({ + target: {tabId: tabs[0].id}, + func: OpenSweetAlert2Modal, + // would have just let it pass thru the object for sweetalert2 - but probably not a good idea lol + args: [request.icon, request.title, request.text] + }) + }) + } +}); + // WHEN CLICKING ON EXTENSION ICON OPEN THE SETTINGS PAGE chrome.action.onClicked.addListener((tab) => { chrome.tabs.create({active: true, url: SettingsURL}); @@ -168,7 +188,9 @@ chrome.contextMenus.removeAll(function () { title: 'Run Update Notifier', id: 'PolyPlus-RunUpdateNotifier', contexts: ['all'], - documentUrlPatterns: ['https://polytoria.com/my/settings/polyplus*'] + documentUrlPatterns: [ + 'https://polytoria.com/my/settings/polyplus*' + ] }); // COPY ASSET ID CONTEXT MENU ITEM REGISTRATION @@ -177,7 +199,13 @@ chrome.contextMenus.removeAll(function () { id: 'PolyPlus-CopyID', contexts: ['link'], documentUrlPatterns: ['https://polytoria.com/*', SettingsURL], - targetUrlPatterns: ['https://polytoria.com/places/**', 'https://polytoria.com/users/**', 'https://polytoria.com/u/**', 'https://polytoria.com/store/**', 'https://polytoria.com/guilds/**'] + targetUrlPatterns: [ + 'https://polytoria.com/places/**', + 'https://polytoria.com/users/**', + 'https://polytoria.com/u/**', + 'https://polytoria.com/store/**', + 'https://polytoria.com/guilds/**' + ] }); // COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION @@ -186,7 +214,9 @@ chrome.contextMenus.removeAll(function () { id: 'PolyPlus-CopyAvatarHash', contexts: ['image'], documentUrlPatterns: ['https://polytoria.com/*', SettingsURL], - targetUrlPatterns: ['https://c0.ptacdn.com/thumbnails/avatars/**', 'https://c0.ptacdn.com/thumbnails/avatars/**'] + targetUrlPatterns: [ + 'https://c0.ptacdn.com/thumbnails/avatars/**' + ] }); }); @@ -236,18 +266,18 @@ chrome.tabs.onActivated.addListener(function (info){ }); function CheckIfScriptApplies(url) { - return Manifest.content_scripts.forEach(script => { - COMMENT - if (matchesUrl(script.matches, url)) { - return true - } - + const matches = Manifest.content_scripts.map(script => { script.matches.forEach(match => { - if (url.startsWith(match.replaceAll('*', ''))) { + console.log(url, match, url.startsWith(match)) + if (url.startsWith(match)) { return true - } + } else { + return false + } }) }) + + return matches } function matchesUrl(patterns, url) { @@ -260,11 +290,8 @@ function matchesUrl(patterns, url) { function CopyAssetID(id) { navigator.clipboard .writeText(id) - .then(() => { - alert('Successfully copied ID!'); - }) - .catch(() => { - alert('Failure to copy ID.'); + .catch((err) => { + alert('Failure to copy ID.', err); }); } @@ -279,6 +306,15 @@ function CopyAvatarHash(hash) { }); } +function OpenSweetAlert2Modal(icon, title, text) { + console.log(window, window.Swal, window.bootstrap) + window.Swal.fire({ + icon: icon, + title: title, + text: text + }) +} + // MergeObjects function was written by ChatGPT cause I was lazy and it was awhile ago function MergeObjects(obj1, obj2) { var mergedObj = {}; @@ -296,10 +332,4 @@ function MergeObjects(obj1, obj2) { } return mergedObj; -} - -chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { - if (request.action === 'reload') { - chrome.runtime.reload(); - } -}); \ No newline at end of file +} \ No newline at end of file diff --git a/js/library-download.js b/js/library-download.js index 432e761..021fea5 100644 --- a/js/library-download.js +++ b/js/library-download.js @@ -2,7 +2,7 @@ const AssetID = window.location.pathname.split('/')[2]; const LibraryType = document.querySelectorAll('ol a')[1].innerText.toLowerCase(); const LibraryTypes = ['model', 'audio', 'decal', 'mesh', 'shirt', 'pant']; -if (LibraryTypes.filter((x) => !LibraryTypes.some(element => element.startsWith(LibraryType))).length > 0) { +if (LibraryTypes.some(element => element.startsWith(LibraryType))) { chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) { Settings = result.PolyPlus_Settings || {}; diff --git a/js/places/place-edit.js b/js/places/place-edit.js index cc3b323..0fc7339 100755 --- a/js/places/place-edit.js +++ b/js/places/place-edit.js @@ -35,28 +35,16 @@ async function ActivityToggle() { ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'; DIV.appendChild(ActivityBtn); - ActivityBtn.addEventListener('click', function () { - fetch(`https://polytoria.com/api/places/${PlaceID}/toggle-active`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value - } - }) - .then((response) => { - if (!response.ok) { - throw new Error('Network not ok ' + response.status); - } - return response.json(); - }) - .then((data) => { - Status = data.isActive; - ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'; - ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success'); - }) - .catch((error) => { - console.log(error); - }); + ActivityBtn.addEventListener('click', async function () { + const Toggle = (await (await fetch(`https://polytoria.com/api/places/${PlaceID}/toggle-active`,{ method: 'POST' })).json()) + console.log(Toggle) + if (Toggle.success) { + Status = data.isActive; + ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'; + ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success'); + } else { + chrome.runtime.sendMessage({ action: "sweetalert2", icon: "error", title: "Error", text: Toggle.message }); + } }); } @@ -93,7 +81,6 @@ function RequestGameProfile() { } async function CopyOwnedPlace() { - console.log('ran function'); if (PlaceData === null) { PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID); PlaceData = await PlaceData.json(); @@ -122,11 +109,6 @@ async function CopyOwnedPlace() { let CreatorToken = await fetch('https://polytoria.com/api/places/edit', { method: 'POST', - /* - headers: { - 'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value - }, - */ body: JSON.stringify({placeID: PlaceID}) }); CreatorToken = await CreatorToken.json(); @@ -144,7 +126,6 @@ async function CopyOwnedPlace() { return response.blob(); }) .then((data) => { - //const JSONBlob = new Blob([data], {type: "application/xml"}) const DownloadURL = URL.createObjectURL(data); const Link = document.createElement('a'); diff --git a/js/places/place-view.js b/js/places/place-view.js index b0ec5d7..bbaf081 100644 --- a/js/places/place-view.js +++ b/js/places/place-view.js @@ -50,6 +50,10 @@ const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [ Utilities = await import(chrome.runtime.getURL('resources/utils.js')); Utilities = Utilities.default; + if (Settings.GD_ServerBalanceOn && PlaceID === '9656') { + TheGreatDivide() + } + if (Settings.PinnedGamesOn === true) { PinnedGames(); } @@ -426,7 +430,7 @@ async function PlaceRevenue() { const ResultText = document.createElement('li'); ResultText.classList = 'fw-normal text-success'; ResultText.style.letterSpacing = '0px'; - ResultText.innerHTML = ` ~` + Revenue.toLocaleString(); + ResultText.innerHTML = ` ~` + Revenue.toLocaleString() + ' '; CalculateRevenueButton.remove(); InfoColumns[1].appendChild(ResultText); @@ -513,3 +517,36 @@ function GetAchievementDifficulty(percent) { return 'Impossible'; } } + +// Temp Feature for The Great Divide event +async function TheGreatDivide() { + const Team = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/greatdivide')).json()).team + if (Team !== undefined) { + const Servers = Array.from(document.getElementById('servers-tabpane').children) + + Servers.forEach(server => { + const TeamCounts = { + phantoms: server.getElementsByClassName('border-phantoms').length, + cobras: server.getElementsByClassName('border-cobras').length + } + + let Enemy = "cobras" + if (Team === "cobras") { Enemy = "phantoms" } + + if (TeamCounts[Team] < TeamCounts[Enemy]) { + console.log(server.getElementsByTagName('button')[0]) + const UnbalancedText = document.createElement('p') + UnbalancedText.classList = 'mb-2' + UnbalancedText.style.fontSize = '0.7rem' + UnbalancedText.style.color = 'orange' + UnbalancedText.innerHTML = `*Potentially Unbalanced ` + + const ServerInfoColumn = server.getElementsByClassName('col-3')[0] + ServerInfoColumn.children[0].style.marginBottom = '0px' + ServerInfoColumn.insertBefore(UnbalancedText, ServerInfoColumn.children[1]) + + Utilities.InjectResource("registerTooltips") + } + }) + } +} \ No newline at end of file diff --git a/js/sitewide.js b/js/sitewide.js index 3b34069..d54f586 100755 --- a/js/sitewide.js +++ b/js/sitewide.js @@ -112,12 +112,11 @@ let Theme = ``; } }); - const combination = "reload"; let currentCombination = ""; document.addEventListener("keypress", function(e) { currentCombination += e.key; - if (currentCombination === combination && document.activeElement.tagName !== "INPUT") { + if (currentCombination === combination && document.activeElement.tagName !== "INPUT" && document.activeElement.tagName !== "TEXTAREA") { console.log("Reloading Poly+..."); chrome.runtime.sendMessage({ action: "reload" }); window.location.reload(); diff --git a/js/store/item-view.js b/js/store/item-view.js index 9b9aa02..af8e093 100755 --- a/js/store/item-view.js +++ b/js/store/item-view.js @@ -44,12 +44,14 @@ var Utilities; } if (Settings.ReplaceItemSalesOn === true) { - const Sales = document.querySelectorAll('.col:has(h6):has(h3.small)')[2]; + const Sales = document.querySelectorAll('.col:has(h6):has(h3.small)')[3]; if (Sales.children[1].innerText === '0') { 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.total.toLocaleString(); + Sales.children[0].innerHTML = `Owners `; + Sales.children[1].innerText = InitialOwners.total.toLocaleString(); + + Utilities.InjectResource("registerTooltips") } } @@ -267,15 +269,12 @@ function TryOnItems() { .then((data) => { switch (AssetType) { case 'Shirt': - console.log('IS SHIRT'); Avatar.shirt = data.url; break; case 'Pants': - console.log('IS PANTS'); Avatar.pants = data.url; break; case 'Face': - console.log('IS FACE'); Avatar.face = data.url; break; } @@ -301,7 +300,7 @@ function TryOnItems() {