chore: format code with Prettier

This commit is contained in:
github-actions[bot] 2024-05-27 22:02:41 +00:00
parent 8f687c53b1
commit 70241eead6
38 changed files with 22284 additions and 6459 deletions

View file

@ -41,9 +41,11 @@ And there is more to come!
# Supported Browsers
As of right now, Poly+ only works on Chromium-based browsers. Currently, there are no plans to bring it to other browsers in the future.
> TL;DR Chromium-based browsers
## Examples of Browsers that are Chromium-based
- Google Chrome
- Chromium
- Edge
@ -56,12 +58,12 @@ As of right now, Poly+ only works on Chromium-based browsers. Currently, there a
## How to Download - Stable Build?
1. Go to the releases section of this GitHub repository
3. Go to the latest release and download the .ZIP file for that release
4. Extract the .ZIP
5. Enable developer mode on your browser (developer mode allows you to load unpacked extensions)
6. Click the "Load Unpacked" button
7. When the file selector comes up, open the unzipped folder from this GitHub repository
8. Go to Polytoria and you should see some changes!
2. Go to the latest release and download the .ZIP file for that release
3. Extract the .ZIP
4. Enable developer mode on your browser (developer mode allows you to load unpacked extensions)
5. Click the "Load Unpacked" button
6. When the file selector comes up, open the unzipped folder from this GitHub repository
7. Go to Polytoria and you should see some changes!
## How to Download - Pre-Release Build?
@ -73,6 +75,6 @@ As of right now, Poly+ only works on Chromium-based browsers. Currently, there a
4. Extract the .ZIP
5. Enable developer mode on your browser (developer mode allows you to load unpacked extensions)
6. Go to your browsers extensions page (usually `browserName://extensions`)
8. Click the "Load Unpacked" button
9. When the file selector comes up, open the unzipped folder of this repository's source code
10. Go to Polytoria and you should see some changes!
7. Click the "Load Unpacked" button
8. When the file selector comes up, open the unzipped folder of this repository's source code
9. Go to Polytoria and you should see some changes!

File diff suppressed because one or more lines are too long

View file

@ -2,15 +2,15 @@
FRONTEND FIXES / SPACING IMPROVEMENTS
*/
body[data-URL^="/my/friends"] .col-lg-3 {
body[data-URL^='/my/friends'] .col-lg-3 {
margin-bottom: 20px;
}
body[data-URL^="/create/"] .mt-2.mt-lg-0.col-lg.d-flex.align-content-between.flex-wrap {
body[data-URL^='/create/'] .mt-2.mt-lg-0.col-lg.d-flex.align-content-between.flex-wrap {
width: 50%;
}
body[data-URL^="/create/"] .col.d-flex.align-content-between.flex-wrap {
body[data-URL^='/create/'] .col.d-flex.align-content-between.flex-wrap {
width: 50%;
}
@ -26,11 +26,19 @@ body[data-URL^="/create/"] .col.d-flex.align-content-between.flex-wrap {
INLINE EDITING
*/
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-visible {display: block !important;}
.polyplus-inlineEditing-visible {display: none;}
body[data-polyplus-inlineEditing='true'] .polyplus-inlineEditing-visible {
display: block !important;
}
.polyplus-inlineEditing-visible {
display: none;
}
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-hidden {display: none !important;}
.polyplus-inlineEditing-hidden {display: block;}
body[data-polyplus-inlineEditing='true'] .polyplus-inlineEditing-hidden {
display: none !important;
}
.polyplus-inlineEditing-hidden {
display: block;
}
/* ------------------------------------------ */
@ -38,7 +46,8 @@ body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-hidden {display
MODALS
*/
html:has(.polyplus-modal[open]), body:has(.polyplus-modal[open]) {
html:has(.polyplus-modal[open]),
body:has(.polyplus-modal[open]) {
overflow: hidden;
}

View file

@ -1,24 +1,24 @@
let PageContainer = document.querySelector('.container.p-0.p-lg-5')
let PageContainer = document.querySelector('.container.p-0.p-lg-5');
let ItemGrid;
let Wearing;
let Tabs;
let IFrame;
let TabSelected = 'hat'
let TabSelected = 'hat';
let Search;
let Page = 1
let Page = 1;
let Avatar = {
"useCharacter": true,
"items": [],
"shirt": null,
"pants": null,
"tool": {ID: -1, URL: null},
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
useCharacter: true,
items: [],
shirt: null,
pants: null,
tool: {ID: -1, URL: null},
headColor: '#e0e0e0',
torsoColor: '#e0e0e0',
leftArmColor: '#e0e0e0',
rightArmColor: '#e0e0e0',
leftLegColor: '#e0e0e0',
rightLegColor: '#e0e0e0'
};
let ItemCardContents = `
<div style="max-width: 150px;">
<div class="card mb-2 avatar-item-container">
@ -37,94 +37,95 @@ let ItemCardContents = `
by <a href="/users/:CreatorID" class="text-reset">:CreatorName</a>
</small>
</div>
`
`;
if (new URLSearchParams(new URL(window.location).search).get('sandbox') === 'true') {
console.log('Avatar Sandbox!')
console.log('Avatar Sandbox!');
LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function (html) {
PageContainer.innerHTML = html
ItemGrid = document.getElementById('inventory')
Wearing = document.getElementById('wearing')
Tabs = document.getElementById('tabs')
IFrame = document.getElementById('viewFrame')
PageContainer.innerHTML = html;
ItemGrid = document.getElementById('inventory');
Wearing = document.getElementById('wearing');
Tabs = document.getElementById('tabs');
IFrame = document.getElementById('viewFrame');
Search = document.getElementById('item-search')
Search = document.getElementById('item-search');
Search.addEventListener('change', function () {
RefreshItems()
RefreshItems();
});
UpdateAvatar()
RefreshItems()
UpdateAvatar();
RefreshItems();
Array.from(Tabs.children).forEach(element => {
Array.from(Tabs.children).forEach((element) => {
element.addEventListener('click', function () {
let Link = element.getElementsByTagName('a')[0]
if (!(Link.classList.contains('active'))) {
Link.classList.add('active')
Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active')
TabSelected = Link.getAttribute('data-tab')
Page = 1
RefreshItems()
let Link = element.getElementsByTagName('a')[0];
if (!Link.classList.contains('active')) {
Link.classList.add('active');
Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active');
TabSelected = Link.getAttribute('data-tab');
Page = 1;
RefreshItems();
}
});
});
let Clear = document.getElementById('clear')
let Clear = document.getElementById('clear');
Clear.addEventListener('click', function () {
Avatar = {
"useCharacter": true,
"items": [],
"shirt": {ID: -1, URL: null},
"pants": {ID: -1, URL: null},
"tool": {ID: -1, URL: null},
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
UpdateAvatar()
useCharacter: true,
items: [],
shirt: {ID: -1, URL: null},
pants: {ID: -1, URL: null},
tool: {ID: -1, URL: null},
headColor: '#e0e0e0',
torsoColor: '#e0e0e0',
leftArmColor: '#e0e0e0',
rightArmColor: '#e0e0e0',
leftLegColor: '#e0e0e0',
rightLegColor: '#e0e0e0'
};
UpdateAvatar();
});
let JSONUpload = document.getElementById('jsonUpload')
let JSONUpload = document.getElementById('jsonUpload');
JSONUpload.addEventListener('change', function () {
let Reader = new FileReader()
let Reader = new FileReader();
Reader.addEventListener('loadend', function () {
Avatar = JSON.parse(Reader.result)
UpdateAvatar()
Avatar = JSON.parse(Reader.result);
UpdateAvatar();
JSONUpload.value = ""
JSONUpload.value = '';
});
Reader.readAsText(JSONUpload.files[0])
Reader.readAsText(JSONUpload.files[0]);
});
let JSONSave = document.getElementById('jsonSave')
let JSONSave = document.getElementById('jsonSave');
JSONSave.addEventListener('click', function () {
FormatAvatar().then(FormattedAvatar => {
let Download = document.createElement('a')
Download.href = URL.createObjectURL(new Blob([JSON.stringify(FormattedAvatar)], {
type: "application/json"
}));
Download.setAttribute('download', 'AvatarSandbox.json')
document.body.appendChild(Download)
Download.click()
document.body.removeChild(Download)
FormatAvatar().then((FormattedAvatar) => {
let Download = document.createElement('a');
Download.href = URL.createObjectURL(
new Blob([JSON.stringify(FormattedAvatar)], {
type: 'application/json'
})
);
Download.setAttribute('download', 'AvatarSandbox.json');
document.body.appendChild(Download);
Download.click();
document.body.removeChild(Download);
});
});
let OpenInNewTab = document.getElementById('openNewTab')
let OpenInNewTab = document.getElementById('openNewTab');
OpenInNewTab.addEventListener('click', function () {
UpdateAvatar()
UpdateAvatar();
});
});
}
function UpdateAvatar() {
GenerateHash()
.then(hash => {
GenerateHash().then((hash) => {
IFrame.addEventListener('load', function () {
IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + hash;
});
@ -134,151 +135,161 @@ function UpdateAvatar() {
function LoadFile(path, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function () { return callback(this.responseText); }
xhr.open("GET", path, true);
xhr.onload = function () {
return callback(this.responseText);
};
xhr.open('GET', path, true);
xhr.send();
}
async function GenerateHash() {
let FormattedAvatar = await FormatAvatar()
let FormattedAvatar = await FormatAvatar();
for (let i = 0; i < FormattedAvatar.items.length; i++) {
FormattedAvatar.items[i] = FormattedAvatar.items[i].URL
FormattedAvatar.items[i] = FormattedAvatar.items[i].URL;
}
if (FormattedAvatar.shirt) {
FormattedAvatar.shirt = FormattedAvatar.shirt.URL
FormattedAvatar.shirt = FormattedAvatar.shirt.URL;
}
if (FormattedAvatar.pants) {
FormattedAvatar.pants = FormattedAvatar.pants.URL
FormattedAvatar.pants = FormattedAvatar.pants.URL;
}
FormattedAvatar.face = FormattedAvatar.face.URL
FormattedAvatar.face = FormattedAvatar.face.URL;
if (FormattedAvatar.tool) {
FormattedAvatar.tool = FormattedAvatar.tool.URL
FormattedAvatar.tool = FormattedAvatar.tool.URL;
}
console.log('Formatted Avatar: ', FormattedAvatar)
console.log('Real Avatar: ', Avatar)
return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)))
console.log('Formatted Avatar: ', FormattedAvatar);
console.log('Real Avatar: ', Avatar);
return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)));
}
async function FormatAvatar() {
let LocalAvatar = structuredClone(Avatar)
let LocalAvatar = structuredClone(Avatar);
if (!LocalAvatar.face) {
LocalAvatar.face = {ID: -1, URL: "https://c0.ptacdn.com/static/3dview/DefaultFace.png"}
LocalAvatar.face = {ID: -1, URL: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'};
}
for (let i = 0; i < LocalAvatar.items.length; i++) {
if (LocalAvatar.items[i].URL === null) {
await fetch("https://api.polytoria.com/v1/assets/serve-mesh/:id".replace(':id', LocalAvatar.items[i].ID))
.then(response => {
await fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', LocalAvatar.items[i].ID))
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Avatar.items[i].URL = data.url
LocalAvatar.items[i].URL = data.url
.then((data) => {
Avatar.items[i].URL = data.url;
LocalAvatar.items[i].URL = data.url;
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
}
if (LocalAvatar.tool && LocalAvatar.tool.ID !== -1 && LocalAvatar.tool.URL === null) {
await fetch("https://api.polytoria.com/v1/assets/serve-mesh/:id".replace(':id', LocalAvatar.tool.ID))
.then(response => {
await fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', LocalAvatar.tool.ID))
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Avatar.tool.URL = data.url
LocalAvatar.tool.URL = data.url
.then((data) => {
Avatar.tool.URL = data.url;
LocalAvatar.tool.URL = data.url;
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
if (LocalAvatar.face.ID !== -1 && LocalAvatar.face.URL === null) {
await fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', LocalAvatar.face.ID))
.then(response => {
await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.face.ID))
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Avatar.face.URL = data.url
LocalAvatar.face.URL = data.url
.then((data) => {
Avatar.face.URL = data.url;
LocalAvatar.face.URL = data.url;
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
if (LocalAvatar.shirt && LocalAvatar.shirt.ID !== -1 && LocalAvatar.shirt.URL === null) {
await fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', LocalAvatar.shirt.ID))
.then(response => {
await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.shirt.ID))
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Avatar.shirt.URL = data.url
LocalAvatar.shirt.URL = data.url
.then((data) => {
Avatar.shirt.URL = data.url;
LocalAvatar.shirt.URL = data.url;
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
if (LocalAvatar.pants && LocalAvatar.pants.ID !== -1 && LocalAvatar.pants.URL === null) {
await fetch("https://api.polytoria.com/v1/assets/serve/:id/Asset".replace(':id', LocalAvatar.pants.ID))
.then(response => {
await fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', LocalAvatar.pants.ID))
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Avatar.pants.URL = data.url
LocalAvatar.pants.URL = data.url
.then((data) => {
Avatar.pants.URL = data.url;
LocalAvatar.pants.URL = data.url;
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
return LocalAvatar
return LocalAvatar;
}
function RefreshItems() {
fetch(`https://api.polytoria.com/v1/store?search=${Search.value}&types%5B%5D=${TabSelected}&sort=createdAt&order=desc&page=${Page}&limit=12`)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Array.from(ItemGrid.children).forEach(element => {element.remove()});
data = data.assets
data.forEach(item => {
let NewItemCard = document.createElement('div')
NewItemCard.classList = 'col-auto'
NewItemCard.innerHTML = ItemCardContents.replace(':ItemName', item.name).replace().replace(':ItemID', item.id).replace(':ItemType', item.type.replace(item.type.charAt(0), item.type.charAt(0).toUpperCase())).replace(':CreatorName', item.creator.name).replace(':CreatorID', item.creator.id).replace(':ItemThumbnail', item.thumbnail)
.then((data) => {
Array.from(ItemGrid.children).forEach((element) => {
element.remove();
});
data = data.assets;
data.forEach((item) => {
let NewItemCard = document.createElement('div');
NewItemCard.classList = 'col-auto';
NewItemCard.innerHTML = ItemCardContents.replace(':ItemName', item.name)
.replace()
.replace(':ItemID', item.id)
.replace(':ItemType', item.type.replace(item.type.charAt(0), item.type.charAt(0).toUpperCase()))
.replace(':CreatorName', item.creator.name)
.replace(':CreatorID', item.creator.id)
.replace(':ItemThumbnail', item.thumbnail);
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
WearAsset(NewItemCard, item.name, {Name: item.creator.name, ID: item.creator.id}, item.id, item.type, item.thumbnail)
WearAsset(NewItemCard, item.name, {Name: item.creator.name, ID: item.creator.id}, item.id, item.type, item.thumbnail);
});
ItemGrid.appendChild(NewItemCard)
ItemGrid.appendChild(NewItemCard);
});
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
@ -286,87 +297,93 @@ function RefreshItems() {
function WearAsset(element, name, creator, id, type, thumbnail) {
switch (type) {
case 'hat':
let Index = CheckItemID(Avatar.items, id)
let Index = CheckItemID(Avatar.items, id);
if (Index === -1) {
if (Avatar.items.length !== 3) {
Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail})
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail});
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
} else {
Avatar.items.splice(0, 1)
Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail})
Avatar.items.splice(0, 1);
Avatar.items.push({Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail});
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
} else {
console.log('remove')
Avatar.items.splice(Index, 1)
console.log('remove');
Avatar.items.splice(Index, 1);
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
break
break;
case 'face':
if (Avatar.face && Avatar.face.ID !== id) {
Avatar.face = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
Avatar.face = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail};
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
} else {
Avatar.face = {Name: "Default Face", Creator: {Name: "Polytoria", ID: 1}, ID: -1, URL: "https://c0.ptacdn.com/static/3dview/DefaultFace.png", Thumbnail: "https://c0.ptacdn.com/static/3dview/DefaultFace.png"}
Avatar.face = {
Name: 'Default Face',
Creator: {Name: 'Polytoria', ID: 1},
ID: -1,
URL: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png',
Thumbnail: 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'
};
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
break
break;
case 'tool':
if (Avatar.tool && Avatar.tool.ID !== id) {
Avatar.tool = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
Avatar.tool = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail};
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
} else {
Avatar.tool = null
Avatar.tool = null;
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
break
break;
case 'shirt':
if (Avatar.shirt.ID !== id) {
Avatar.shirt = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
Avatar.shirt = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail};
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
} else {
Avatar.shirt = null
Avatar.shirt = null;
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
break
break;
case 'pants':
if (Avatar.pants.ID !== id) {
Avatar.pants = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail}
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
Avatar.pants = {Name: name, Creator: creator, ID: id, URL: null, Thumbnail: thumbnail};
Wearing.prepend(ItemGrid.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
} else {
Avatar.pants = null
Avatar.pants = null;
if (TabSelected === type) {
console.log('tab is', TabSelected, type)
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`))
console.log('tab is', TabSelected, type);
ItemGrid.prepend(Wearing.querySelector(`.col-auto:has(a[href="/store/${id}"])`));
}
}
break
break;
}
UpdateAvatar()
UpdateAvatar();
}
function CheckItemID(object, id) {
for (let i = 0; i < object.length; i++) {
if (object[i] === id || object[i].ID === id) {
console.log('Index: ' + i)
return i
console.log('Index: ' + i);
return i;
}
}
return -1
return -1;
}

View file

@ -1,199 +1,196 @@
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID
const UserID = JSON.parse(window.localStorage.getItem('p+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"
]
'#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 PageContainer = document.querySelector('.container.p-0.p-lg-5');
let ItemGrid;
let Wearing;
let Tabs;
let IFrame;
let TabSelected = 'hat'
let TabSelected = 'hat';
let Search;
let Page = 1
let Page = 1;
let Avatar = {
"useCharacter": true,
"items": [
24122
],
"shirt": 24118,
"pants": 24123,
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
useCharacter: true,
items: [24122],
shirt: 24118,
pants: 24123,
headColor: '#e0e0e0',
torsoColor: '#e0e0e0',
leftArmColor: '#e0e0e0',
rightArmColor: '#e0e0e0',
leftLegColor: '#e0e0e0',
rightLegColor: '#e0e0e0'
};
if (new URLSearchParams(window.location.search).has('sandbox')) {
console.log('Avatar Sandbox!')
console.log('Avatar Sandbox!');
LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function (html) {
PageContainer.innerHTML = html
ItemGrid = document.getElementById('inventory')
Wearing = document.getElementById('wearing')
Tabs = document.getElementById('tabs')
IFrame = document.getElementById('viewFrame')
PageContainer.innerHTML = html;
ItemGrid = document.getElementById('inventory');
Wearing = document.getElementById('wearing');
Tabs = document.getElementById('tabs');
IFrame = document.getElementById('viewFrame');
Search = document.getElementById('item-search')
Search = document.getElementById('item-search');
Search.addEventListener('onchange', function () {
RefreshItems()
RefreshItems();
});
UpdateAvatar()
RefreshItems()
LoadWearing()
UpdateAvatar();
RefreshItems();
LoadWearing();
Array.from(Tabs.children).forEach(element => {
Array.from(Tabs.children).forEach((element) => {
element.addEventListener('click', function () {
let Link = element.getElementsByTagName('a')[0]
if (!(Link.classList.contains('active'))) {
Link.classList.add('active')
Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active')
TabSelected = Link.getAttribute('data-tab')
Page = 1
RefreshItems()
let Link = element.getElementsByTagName('a')[0];
if (!Link.classList.contains('active')) {
Link.classList.add('active');
Tabs.querySelector(`[data-tab="${TabSelected}"]`).classList.remove('active');
TabSelected = Link.getAttribute('data-tab');
Page = 1;
RefreshItems();
}
});
});
let Clear = document.getElementById('clear')
let Clear = document.getElementById('clear');
Clear.addEventListener('click', function () {
Avatar = {
"useCharacter": true,
"items": [
24122
],
"shirt": 24118,
"pants": 24123,
"headColor": "#e0e0e0",
"torsoColor": "#e0e0e0",
"leftArmColor": "#e0e0e0",
"rightArmColor": "#e0e0e0",
"leftLegColor": "#e0e0e0",
"rightLegColor": "#e0e0e0"
}
UpdateAvatar()
useCharacter: true,
items: [24122],
shirt: 24118,
pants: 24123,
headColor: '#e0e0e0',
torsoColor: '#e0e0e0',
leftArmColor: '#e0e0e0',
rightArmColor: '#e0e0e0',
leftLegColor: '#e0e0e0',
rightLegColor: '#e0e0e0'
};
UpdateAvatar();
});
let Myself = document.getElementById('myself')
let Myself = document.getElementById('myself');
Myself.addEventListener('click', function () {
LoadMyself()
LoadMyself();
});
let JSONUpload = document.getElementById('jsonUpload')
let JSONUpload = document.getElementById('jsonUpload');
JSONUpload.addEventListener('change', function () {
let Reader = new FileReader()
let Reader = new FileReader();
Reader.addEventListener('loadend', function () {
Avatar = JSON.parse(Reader.result)
UpdateAvatar()
Avatar = JSON.parse(Reader.result);
UpdateAvatar();
JSONUpload.value = ""
JSONUpload.value = '';
});
Reader.readAsText(JSONUpload.files[0])
Reader.readAsText(JSONUpload.files[0]);
});
let JSONSave = document.getElementById('jsonSave')
let JSONSave = document.getElementById('jsonSave');
JSONSave.addEventListener('click', function () {
let Download = document.createElement('a')
Download.href = URL.createObjectURL(new Blob([JSON.stringify(Avatar)], {
type: "application/json"
}));
Download.setAttribute('download', 'AvatarSandbox.json')
document.body.appendChild(Download)
Download.click()
document.body.removeChild(Download)
});
let OpenInNewTab = document.getElementById('openNewTab')
OpenInNewTab.addEventListener('click', function(){
UpdateAvatar()
});
let LoadAsset = document.getElementById('load-asset')
LoadAsset.addEventListener('click', async function(){
console.log('clickk')
const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + LoadAsset.previousElementSibling.value)).json()).url
Avatar.items.push(MeshURL)
UpdateAvatar()
let Download = document.createElement('a');
Download.href = URL.createObjectURL(
new Blob([JSON.stringify(Avatar)], {
type: 'application/json'
})
);
Download.setAttribute('download', 'AvatarSandbox.json');
document.body.appendChild(Download);
Download.click();
document.body.removeChild(Download);
});
let OpenInNewTab = document.getElementById('openNewTab');
OpenInNewTab.addEventListener('click', function () {
UpdateAvatar();
});
let LoadAsset = document.getElementById('load-asset');
LoadAsset.addEventListener('click', async function () {
console.log('clickk');
const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + LoadAsset.previousElementSibling.value)).json()).url;
Avatar.items.push(MeshURL);
UpdateAvatar();
});
});
} else {
const SandboxButton = document.createElement('a')
SandboxButton.classList = 'btn btn-outline-success w-100 mt-3'
SandboxButton.href = '?sandbox=true'
SandboxButton.innerHTML = '<i class="fas fa-shirt"></i> Avatar Sandbox'
document.getElementById('cont-move').parentElement.appendChild(SandboxButton)
const SandboxButton = document.createElement('a');
SandboxButton.classList = 'btn btn-outline-success w-100 mt-3';
SandboxButton.href = '?sandbox=true';
SandboxButton.innerHTML = '<i class="fas fa-shirt"></i> Avatar Sandbox';
document.getElementById('cont-move').parentElement.appendChild(SandboxButton);
}
function UpdateAvatar() {
GenerateHash()
.then(hash => {
GenerateHash().then((hash) => {
IFrame.addEventListener('load', function () {
IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + hash;
});
@ -203,37 +200,41 @@ function UpdateAvatar() {
function LoadFile(path, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function () { return callback(this.responseText); }
xhr.open("GET", path, true);
xhr.onload = function () {
return callback(this.responseText);
};
xhr.open('GET', path, true);
xhr.send();
}
async function GenerateHash(data) {
if (!data) {
console.log('Data not provided')
let FormattedAvatar = await FormatAvatar()
return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)))
console.log('Data not provided');
let FormattedAvatar = await FormatAvatar();
return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)));
} else {
console.log('Data provided')
return btoa(encodeURIComponent(JSON.stringify(data)))
console.log('Data provided');
return btoa(encodeURIComponent(JSON.stringify(data)));
}
}
function RefreshItems() {
fetch(`https://api.polytoria.com/v1/store?search=${Search.value}&types%5B%5D=${TabSelected}&sort=createdAt&order=desc&page=${Page}&limit=12`)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Array.from(ItemGrid.children).forEach(element => {element.remove()});
data = data.assets
data.forEach(item => {
let NewItemCard = document.createElement('div')
NewItemCard.setAttribute('data-id', item.id)
NewItemCard.classList = 'col-auto'
.then((data) => {
Array.from(ItemGrid.children).forEach((element) => {
element.remove();
});
data = data.assets;
data.forEach((item) => {
let NewItemCard = document.createElement('div');
NewItemCard.setAttribute('data-id', item.id);
NewItemCard.classList = 'col-auto';
NewItemCard.innerHTML = `
<div style="max-width: 150px;">
<div class="card mb-2 avatar-item-container">
@ -252,205 +253,211 @@ function RefreshItems() {
by <a href="/users/${item.creator.id}" class="text-reset">${item.creator.name}</a>
</small>
</div>
`
`;
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
WearAsset(NewItemCard, item)
WearAsset(NewItemCard, item);
});
ItemGrid.appendChild(NewItemCard)
ItemGrid.appendChild(NewItemCard);
});
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
async function FormatAvatar() {
const FormattedAvatar = structuredClone(Avatar)
const FormattedAvatar = structuredClone(Avatar);
// Hats, Tools: https://api.polytoria.com/v1/assets/serve-mesh/:id
// or: https://api.polytoria.com/v1/assets/serve/:id/Asset
Avatar.items.forEach(async (item, index) => {
if (typeof(item) === 'number') {
console.log(item)
if (typeof item === 'number') {
console.log(item);
await FetchMesh(item)
.then(URL => {
console.log('URL: ' + URL)
FormattedAvatar.items[index] = URL
.then((URL) => {
console.log('URL: ' + URL);
FormattedAvatar.items[index] = URL;
})
.catch(error => {
throw new Error(error)
.catch((error) => {
throw new Error(error);
});
console.log('after url')
console.log('after url');
//Avatar.items[index] = URL
}
});
if (typeof(FormattedAvatar.tool) === 'number') {console.log(FormattedAvatar.tool); FormattedAvatar.tool = await FetchMesh(FormattedAvatar.tool)}
if (FormattedAvatar.face && typeof(FormattedAvatar.face) === 'number') {
FormattedAvatar.face = await FetchAsset(FormattedAvatar.face)
} else {
FormattedAvatar.face = "https://c0.ptacdn.com/static/3dview/DefaultFace.png"
if (typeof FormattedAvatar.tool === 'number') {
console.log(FormattedAvatar.tool);
FormattedAvatar.tool = await FetchMesh(FormattedAvatar.tool);
}
if (typeof(FormattedAvatar.shirt) === 'number') {FormattedAvatar.shirt = await FetchAsset(FormattedAvatar.shirt)}
if (typeof(FormattedAvatar.pants) === 'number') {FormattedAvatar.pants = await FetchAsset(FormattedAvatar.pants)}
if (FormattedAvatar.face && typeof FormattedAvatar.face === 'number') {
FormattedAvatar.face = await FetchAsset(FormattedAvatar.face);
} else {
FormattedAvatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png';
}
console.log('Real Avatar: ', Avatar, 'Formatted: ', FormattedAvatar)
return FormattedAvatar
if (typeof FormattedAvatar.shirt === 'number') {
FormattedAvatar.shirt = await FetchAsset(FormattedAvatar.shirt);
}
if (typeof FormattedAvatar.pants === 'number') {
FormattedAvatar.pants = await FetchAsset(FormattedAvatar.pants);
}
console.log('Real Avatar: ', Avatar, 'Formatted: ', FormattedAvatar);
return FormattedAvatar;
}
function LoadMyself() {
fetch('https://api.polytoria.com/v1/users/:id/avatar'.replace(':id', UserID))
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
Avatar.items = []
data.assets.forEach(item => {
switch(item.type) {
case 'hat':
Avatar.items.push(item.id)
break
default:
Avatar[item.type] = item.id
break
}
});
Avatar.headColor = '#' + data.colors.head || '#cdcdcd'
Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd'
Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd'
Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd'
Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd'
Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd'
UpdateAvatar()
})
.catch(error => {
console.log(error)
});
}
function WearAsset(element, info) {
if (Avatar.items.indexOf(info.id) === -1 && Avatar[info.type] !== info.id) {
console.log('Equip', info)
switch(info.type) {
case 'hat':
Avatar.items.push(info.id)
break
default:
Avatar[info.type] = info.id
break
}
} else {
console.log('unequip', info)
switch(info.type) {
case 'hat':
Avatar.items.splice(Avatar.items.indexOf(info.id), 1)
break
case 'face':
Avatar.face = "https://c0.ptacdn.com/static/3dview/DefaultFace.png"
break
default:
Avatar[info.type] = undefined
break
}
}
const ToggleButton = element.getElementsByClassName('avatarAction')[0]
ToggleButton.classList.toggle('btn-success')
ToggleButton.classList.toggle('btn-danger')
ToggleButton.children[0].classList.toggle('fa-plus')
ToggleButton.children[0].classList.toggle('fa-minus')
const Duplicate = ItemGrid.querySelector(`[data-id="${info.id}"]`)
if (Duplicate !== null && Duplicate !== element) {
const DuplicateToggleButton = Duplicate.getElementsByClassName('avatarAction')[0]
DuplicateToggleButton.classList.toggle('btn-success')
DuplicateToggleButton.classList.toggle('btn-danger')
DuplicateToggleButton.children[0].classList.toggle('fa-plus')
DuplicateToggleButton.children[0].classList.toggle('fa-minus')
}
LoadWearing()
UpdateAvatar()
}
async function FetchMesh(id) {
if (id === null) {return null}
console.log('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id))
return fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id))
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
console.log(data, 'finished', data.url)
return data.url
})
.catch(error => {
console.log('Fetch error: ' + error)
});
}
async function FetchAsset(id) {
if (id === null) {return null}
return fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', id))
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
return data.url
})
.catch(error => {
console.log('Fetch error: ' + error)
});
}
function LoadWearing() {
const WearingItems = [
...Avatar.items,
Avatar.shirt,
Avatar.pants,
Avatar.face
].filter(item => item !== null && item !== undefined);
Array.from(Wearing.children).forEach(element => {
const ItemID = element.getElementsByTagName('a')[0].href.split('/')[2]
if (!WearingItems.includes(ItemID)) {
element.remove();
}
});
WearingItems.forEach(item => {
const ExistingElement = Wearing.querySelector(`[data-itemid="${item}"]`);
if (!ExistingElement) {
fetch(`https://api.polytoria.com/v1/store/${item}`)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then(item => {
.then((data) => {
Avatar.items = [];
data.assets.forEach((item) => {
switch (item.type) {
case 'hat':
Avatar.items.push(item.id);
break;
default:
Avatar[item.type] = item.id;
break;
}
});
Avatar.headColor = '#' + data.colors.head || '#cdcdcd';
Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd';
Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd';
Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd';
Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd';
Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd';
UpdateAvatar();
})
.catch((error) => {
console.log(error);
});
}
function WearAsset(element, info) {
if (Avatar.items.indexOf(info.id) === -1 && Avatar[info.type] !== info.id) {
console.log('Equip', info);
switch (info.type) {
case 'hat':
Avatar.items.push(info.id);
break;
default:
Avatar[info.type] = info.id;
break;
}
} else {
console.log('unequip', info);
switch (info.type) {
case 'hat':
Avatar.items.splice(Avatar.items.indexOf(info.id), 1);
break;
case 'face':
Avatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png';
break;
default:
Avatar[info.type] = undefined;
break;
}
}
const ToggleButton = element.getElementsByClassName('avatarAction')[0];
ToggleButton.classList.toggle('btn-success');
ToggleButton.classList.toggle('btn-danger');
ToggleButton.children[0].classList.toggle('fa-plus');
ToggleButton.children[0].classList.toggle('fa-minus');
const Duplicate = ItemGrid.querySelector(`[data-id="${info.id}"]`);
if (Duplicate !== null && Duplicate !== element) {
const DuplicateToggleButton = Duplicate.getElementsByClassName('avatarAction')[0];
DuplicateToggleButton.classList.toggle('btn-success');
DuplicateToggleButton.classList.toggle('btn-danger');
DuplicateToggleButton.children[0].classList.toggle('fa-plus');
DuplicateToggleButton.children[0].classList.toggle('fa-minus');
}
LoadWearing();
UpdateAvatar();
}
async function FetchMesh(id) {
if (id === null) {
return null;
}
console.log('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id));
return fetch('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id))
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then((data) => {
console.log(data, 'finished', data.url);
return data.url;
})
.catch((error) => {
console.log('Fetch error: ' + error);
});
}
async function FetchAsset(id) {
if (id === null) {
return null;
}
return fetch('https://api.polytoria.com/v1/assets/serve/:id/Asset'.replace(':id', id))
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then((data) => {
return data.url;
})
.catch((error) => {
console.log('Fetch error: ' + error);
});
}
function LoadWearing() {
const WearingItems = [...Avatar.items, Avatar.shirt, Avatar.pants, Avatar.face].filter((item) => item !== null && item !== undefined);
Array.from(Wearing.children).forEach((element) => {
const ItemID = element.getElementsByTagName('a')[0].href.split('/')[2];
if (!WearingItems.includes(ItemID)) {
element.remove();
}
});
WearingItems.forEach((item) => {
const ExistingElement = Wearing.querySelector(`[data-itemid="${item}"]`);
if (!ExistingElement) {
fetch(`https://api.polytoria.com/v1/store/${item}`)
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then((item) => {
if (Wearing.innerHTML === 'No items to show.') {
Wearing.innerHTML = ''
Wearing.innerHTML = '';
}
let NewItemCard = document.createElement('div');
NewItemCard.setAttribute('data-id', item.id)
NewItemCard.setAttribute('data-id', item.id);
NewItemCard.classList = 'col-auto';
NewItemCard.innerHTML = `
<div style="max-width: 150px;">
@ -470,19 +477,19 @@ function LoadWearing() {
by <a href="/users/${item.creator.id}" class="text-reset">${item.creator.name}</a>
</small>
</div>
`
`;
Wearing.appendChild(NewItemCard);
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
WearAsset(NewItemCard, item);
});
})
.catch(error => {
.catch((error) => {
console.log('Fetch error: ' + error);
});
}
});
if (Array.from(Wearing.children).length === 0) {
Wearing.innerHTML = 'No items to show.'
Wearing.innerHTML = 'No items to show.';
}
}

View file

@ -1,38 +1,37 @@
var SelectedFriends = []
var SelectedFriends = [];
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings;
if (Settings.ImprovedFrListsOn === true) {
var Tab = "requests"
var Tab = 'requests';
var FriendsContainer = document.getElementById('friends-container')
var Container = document.createElement('div')
Container.classList = 'row mb-3'
var FriendsContainer = document.getElementById('friends-container');
var Container = document.createElement('div');
Container.classList = 'row mb-3';
Container.innerHTML = `
<div class="col"><button id="AccAllFrBtn" class="btn btn-success w-100">Accept all Friend Request(s)</button></div>
<div class="col"><button id="DelAllFrBtn" class="btn btn-danger w-100">Decline all Friend Request(s)</button></div>
`
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)"]')
`;
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)
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 => {
body: JSON.stringify({userID: parseInt(element.getAttribute('data-user-id'))})
}).catch((error) => {
// Handle any errors
console.error('Error:', error);
Success = false
Success = false;
});
/*
@ -44,27 +43,26 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
FriendsContainer.appendChild(NewAcceptBtn)
NewAcceptBtn.click();
*/
})
});
});
} else {
AccAllFrBtn.setAttribute('disabled', 'true')
AccAllFrBtn.setAttribute('disabled', 'true');
}
if (!(DelBtns.length === 0)) {
DelAllFrBtn.addEventListener('click', function () {
DelBtns.forEach(element => {
setTimeout(function () {}, 110)
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 => {
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
Success = false;
});
/*
@ -76,135 +74,137 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
FriendsContainer.appendChild(NewDeclineBtn)
NewDeclineBtn.click();
*/
})
});
});
} else {
DelAllFrBtn.setAttribute('disabled', 'true')
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'
let Text = document.createElement('p');
Text.classList = 'mx-auto';
Text.style.textAlign = 'center';
Text.style.fontSize = '1.3rem';
Text.style.display = 'none';
Text.innerHTML = `
<span>0</span> friends selected!
<br>
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
<button id="removeSelectionBtn" class="btn btn-danger">Remove Selected Friends</button>
`
FriendsContainer.parentElement.insertBefore(Text, FriendsContainer)
`;
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"
Tab = 'requests';
Container.style.display = '';
Text.style.display = 'none';
document.querySelectorAll('input[type="check"]').forEach(element => {element.remove();});
document.querySelectorAll('input[type="check"]').forEach((element) => {
element.remove();
});
});
document.querySelector('[data-friends-tab="friends"]').addEventListener('click', function () {
Tab = "friends"
Tab = 'friends';
Container.style.display = 'none';
Text.style.display = '';
});
var ConfirmRemove = 0
var ConfirmRemove = 0;
Text_View.addEventListener('click', function () {});
Text_Clear.addEventListener('click', function () {
SelectedFriends = []
SelectedFriends = [];
UpdateCheckboxes();
Text_Span.innerText = SelectedFriends.length
Text_Span.innerText = SelectedFriends.length;
});
Text_Remove.addEventListener('click', function () {
ConfirmRemove = ConfirmRemove + 1
ConfirmRemove = ConfirmRemove + 1;
switch (ConfirmRemove) {
case 0:
Text_Remove.innerText = 'Remove Selected Friends'
break
Text_Remove.innerText = 'Remove Selected Friends';
break;
case 1:
Text_Remove.innerText = 'Are you sure?'
break
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)
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 = []
SelectedFriends = [];
UpdateCheckboxes();
Text_Remove.innerText = 'Remove Selected Friends'
ConfirmRemove = 0
break
Text_Remove.innerText = 'Remove Selected Friends';
ConfirmRemove = 0;
break;
}
});
const observer = new MutationObserver(function () {
if (FriendsContainer.children.length > 0 && Tab === "friends") {
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;')
var Index = SelectedFriends.indexOf(UserID)
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'
DeclineBtn.classList.add('disabled');
NewCheckBox.style.borderColor = 'lime';
}
EditColumn.classList.remove('col-9')
EditColumn.classList.add('col')
Column.appendChild(NewCheckBox)
EditColumn.parentElement.appendChild(Column)
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)
var Index = SelectedFriends.indexOf(UserID);
if (Index === -1) {
DeclineBtn.classList.add('disabled')
SelectedFriends.push(UserID)
NewCheckBox.style.borderColor = 'lime'
DeclineBtn.classList.add('disabled');
SelectedFriends.push(UserID);
NewCheckBox.style.borderColor = 'lime';
} else {
SelectedFriends.splice(Index, 1)
NewCheckBox.style.borderColor = '#393939'
DeclineBtn.classList.remove('disabled')
SelectedFriends.splice(Index, 1);
NewCheckBox.style.borderColor = '#393939';
DeclineBtn.classList.remove('disabled');
}
Text_Span.innerText = SelectedFriends.length
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')
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')
element.removeAttribute('disabled');
}
if (SelectedFriends.IndexOf(DeclineBtn.getAttribute('data-user-id')) === -1) {
element.style.borderColor = '#393939'
DeclineBtn.classList.remove('disabled')
element.style.borderColor = '#393939';
DeclineBtn.classList.remove('disabled');
if (SelectedFriends.length >= 25) {
element.setAttribute('disabled', true)
element.setAttribute('disabled', true);
}
} else {
DeclineBtn.classList.add('disabled')
element.style.borderColor = 'lime'
DeclineBtn.classList.add('disabled');
element.style.borderColor = 'lime';
}
})
});
}
}
});

View file

@ -3,24 +3,24 @@ this file needs a rewrite by me lol
*/
var Settings;
var PinnedGamesData
var BestFriendsData
var PinnedGamesData;
var BestFriendsData;
let Utilities;
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
Settings = result.PolyPlus_Settings || Utilities.DefaultSettings
Settings = result.PolyPlus_Settings || Utilities.DefaultSettings;
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
IRLPrice();
}
if (Settings.HomeFriendCountOn === true) {
ShowFriendCount()
ShowFriendCount();
}
if (Settings.PinnedGamesOn === true || Settings.BestFriendsOn === true) {
Update()
Update();
}
});
@ -56,39 +56,39 @@ let TitleElement = `
<h6 class="dash-ctitle2">Jump right back into your favorite games</h6>
<h5 class="dash-ctitle">Pinned Games</h5>
</div>`;
var FriendContainer = document.querySelector('.card:has(.friendsPopup) .card-body')
var FriendContainer = document.querySelector('.card:has(.friendsPopup) .card-body');
let NewContainer = document.createElement('div');
NewContainer.style.display = 'none'
NewContainer.style.display = 'none';
NewContainer.classList = 'card card-dash mcard';
NewContainer.style.animationDelay = '0.18s';
NewContainer.innerHTML = ContainerElement;
let NewTitle = document.createElement('div');
NewTitle.style.display = 'none'
NewTitle.style.display = 'none';
NewTitle.classList = 'row reqFadeAnim px-2 px-lg-0';
NewTitle.innerHTML = TitleElement;
let BestFriendsContainer = document.createElement('div')
BestFriendsContainer.classList = 'd-flex'
BestFriendsContainer.style = 'display: none; border-bottom: 1px solid #000; padding-bottom: 10px; margin-bottom: 10px; width: 100%;'
let BestFriendsContainer = document.createElement('div');
BestFriendsContainer.classList = 'd-flex';
BestFriendsContainer.style = 'display: none; border-bottom: 1px solid #000; padding-bottom: 10px; margin-bottom: 10px; width: 100%;';
let Spacer = document.createElement('div')
Spacer.innerHTML = ' '
Spacer.style.width = '50px'
Spacer.prepend(BestFriendsContainer)
let Spacer = document.createElement('div');
Spacer.innerHTML = ' ';
Spacer.style.width = '50px';
Spacer.prepend(BestFriendsContainer);
FriendContainer.prepend(BestFriendsContainer)
FriendContainer.prepend(BestFriendsContainer);
async function Update() {
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
PinnedGamesData = result.PolyPlus_PinnedGames || [];
if (Settings.PinnedGamesOn === true) {
PinnedGames()
PinnedGames();
} else {
NewContainer.style.display = 'none'
NewTitle.style.display = 'none'
NewContainer.style.display = 'none';
NewTitle.style.display = 'none';
}
});
@ -98,36 +98,39 @@ async function Update() {
if (Settings.BestFriendsOn === true) {
BestFriends();
} else {
BestFriendsContainer.style.display = 'none'
Spacer.style.display = 'none'
BestFriendsContainer.style.display = 'none';
Spacer.style.display = 'none';
}
});
}
function PinnedGames() {
var Existing = NewContainer.children[0].children
Array.from(Existing).forEach(element => {
var Existing = NewContainer.children[0].children;
Array.from(Existing).forEach((element) => {
element.remove();
});
if (PinnedGamesData.length === 0) {
NewContainer.style.display = 'none'
NewTitle.style.display = 'none'
NewContainer.style.display = 'none';
NewTitle.style.display = 'none';
} else {
NewContainer.style.display = ''
NewTitle.style.display = ''
NewContainer.style.display = '';
NewTitle.style.display = '';
}
PinnedGamesData.forEach(element => {
PinnedGamesData.forEach((element) => {
fetch('https://api.polytoria.com/v1/places/' + element)
.then(response => response.json())
.then(data => {
.then((response) => response.json())
.then((data) => {
let GameName = data.name;
let GameThumbnail = data.thumbnail;
var NewGameContainer = document.createElement('a');
NewGameContainer.innerHTML = GameContainerElement.replace(':GameName',GameName).replace(':Thumbnail',GameThumbnail).replace(':Likes', data.rating.likes).replace(':Dislikes', data.rating.dislikes);
NewGameContainer.href = '/places/' + element
NewGameContainer.innerHTML = GameContainerElement.replace(':GameName', GameName)
.replace(':Thumbnail', GameThumbnail)
.replace(':Likes', data.rating.likes)
.replace(':Dislikes', data.rating.dislikes);
NewGameContainer.href = '/places/' + element;
/*
if (new Date().getDate() >= new Date(data.updatedAt).getDate()) {
@ -137,66 +140,66 @@ function PinnedGames() {
NewContainer.children[0].appendChild(NewGameContainer);
})
.catch(error => {
.catch((error) => {
console.error('Error:', error);
});
});
}
function BestFriends() {
Array.from(document.querySelectorAll('[bestFriend]')).forEach(element => {
element.removeAttribute('bestFriend')
Array.from(document.querySelectorAll('[bestFriend]')).forEach((element) => {
element.removeAttribute('bestFriend');
element.getElementsByClassName('friend-name')[0].style.color = 'initial';
FriendContainer.appendChild(element)
FriendContainer.appendChild(element);
});
if (BestFriendsData.length === 0) {
BestFriendsContainer.style.visibility = 'hidden'
BestFriendsContainer.style.padding = '0px !important'
BestFriendsContainer.style.margin = '0px !important'
BestFriendsContainer.style.visibility = 'hidden';
BestFriendsContainer.style.padding = '0px !important';
BestFriendsContainer.style.margin = '0px !important';
} else {
BestFriendsContainer.style.visibility = 'visible'
BestFriendsContainer.style.padding = ''
BestFriendsContainer.style.margin = ''
BestFriendsContainer.style.visibility = 'visible';
BestFriendsContainer.style.padding = '';
BestFriendsContainer.style.margin = '';
}
BestFriendsData.forEach(element => {
let ExistingFriend = document.getElementById('friend-' + element)
BestFriendsData.forEach((element) => {
let ExistingFriend = document.getElementById('friend-' + element);
if (ExistingFriend) {
ExistingFriend.setAttribute('bestFriend', 'true')
ExistingFriend.setAttribute('bestFriend', 'true');
ExistingFriend.getElementsByClassName('friend-name')[0].style.color = 'yellow';
BestFriendsContainer.prepend(ExistingFriend)
BestFriendsContainer.prepend(ExistingFriend);
}
});
}
var SecondaryColumn = document.getElementsByClassName('col-lg-8')[0]
var SecondaryColumn = document.getElementsByClassName('col-lg-8')[0];
SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[0]);
SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]);
async function IRLPrice() {
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
const TrendingItems = document.getElementById('home-trendingItems')
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 Price = item.getElementsByClassName('text-success')[0];
if (Price !== undefined) {
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency);
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)
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);
}
}
})();
}
async function ShowFriendCount() {
let FriendCount = (await (await fetch('https://polytoria.com/api/friends?page=1')).json()).meta.total
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) {
@ -207,9 +210,9 @@ async function ShowFriendCount() {
}
*/
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)
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);
}

View file

@ -1,47 +1,47 @@
ExpandMessages()
ExpandMessages();
function ExpandMessages() {
const Messages = document.getElementById('messages')
const Messages = document.getElementById('messages');
for (let message of Messages.children) {
let Expanded = false
let ContentDiv = null
let Expanded = false;
let ContentDiv = null;
const ViewButton = message.querySelector('a.btn[href^="/inbox/messages"]')
const MessageID = ViewButton.getAttribute('href').split('/')[3]
const ViewButton = message.querySelector('a.btn[href^="/inbox/messages"]');
const MessageID = ViewButton.getAttribute('href').split('/')[3];
const ExpandButton = document.createElement('button')
ExpandButton.classList = 'btn btn-outline-warning px-4 mt-1'
ExpandButton.innerText = 'Expand'
ViewButton.parentElement.appendChild(ExpandButton)
const ExpandButton = document.createElement('button');
ExpandButton.classList = 'btn btn-outline-warning px-4 mt-1';
ExpandButton.innerText = 'Expand';
ViewButton.parentElement.appendChild(ExpandButton);
ExpandButton.addEventListener('click', function () {
if (ContentDiv === null) {
fetch('https://polytoria.com/inbox/messages/' + MessageID)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.text()
return response.text();
})
.then(data => {
const Doc = new DOMParser().parseFromString(data, 'text/html')
const MessageContent = Doc.querySelector('p.mb-0').innerText
.then((data) => {
const Doc = new DOMParser().parseFromString(data, 'text/html');
const MessageContent = Doc.querySelector('p.mb-0').innerText;
ContentDiv = document.createElement('div')
ContentDiv.classList = 'py-2'
ContentDiv.innerText = MessageContent
message.appendChild(ContentDiv)
ContentDiv = document.createElement('div');
ContentDiv.classList = 'py-2';
ContentDiv.innerText = MessageContent;
message.appendChild(ContentDiv);
})
.catch(error => {
console.log(error)
.catch((error) => {
console.log(error);
});
}
Expanded = !Expanded
Expanded = !Expanded;
ExpandButton.innerText = (Expanded === false) ? 'Expand' : 'Minimize'
ContentDiv.style.display = (Expanded === false) ? 'none' : 'block'
ExpandButton.innerText = Expanded === false ? 'Expand' : 'Minimize';
ContentDiv.style.display = Expanded === false ? 'none' : 'block';
});
}
}

View file

@ -1,19 +1,19 @@
if (window.location.pathname.split('/')[3] === "inventory") {
const UserID = window.location.pathname.split('/')[2]
if (window.location.pathname.split('/')[3] === 'inventory') {
const UserID = window.location.pathname.split('/')[2];
if (UserID === JSON.parse(window.localStorage.getItem('p+account_info')).ID) {
let Nav = document.getElementsByClassName('nav-pills')[0]
let WishlistNav = document.createElement('li')
WishlistNav.classList.add('nav-item')
let Nav = document.getElementsByClassName('nav-pills')[0];
let WishlistNav = document.createElement('li');
WishlistNav.classList.add('nav-item');
WishlistNav.innerHTML = `
<a href="/users/${UserID}/inventory/wishlist/" class="nav-link">
<i class="fa-regular fa-sparkles me-1"></i>
<span class="pilltitle">Item Wishlist</span>
</a>
`
Nav.appendChild(WishlistNav)
`;
Nav.appendChild(WishlistNav);
if (window.location.pathname.split('/')[4] === "wishlist") {
const ItemGrid = document.getElementsByClassName('itemgrid')[0]
if (window.location.pathname.split('/')[4] === 'wishlist') {
const ItemGrid = document.getElementsByClassName('itemgrid')[0];
const ItemCardContents = `
<a href="/store/:ItemID" class="text-reset">
<div class="card mb-2">
@ -30,22 +30,22 @@ if (window.location.pathname.split('/')[3] === "inventory") {
by <a href="/users/:CreatorID" class="text-muted">:CreatorName</a>
</small>
<button class="polyplus-itemwish-removebtn btn btn-danger btn-sm" style="width: 100%;">X</button>
`
`;
Array.from(ItemGrid.children).forEach(element => {
Array.from(ItemGrid.children).forEach((element) => {
element.remove();
});
Array.from(Nav.children).forEach(element => {
element = element.children[0]
Array.from(Nav.children).forEach((element) => {
element = element.children[0];
if (!(element === WishlistNav)) {
if (element.classList.contains('active')) {
element.classList.remove('active')
element.classList.remove('active');
}
}
});
WishlistNav.children[0].classList.add('active')
const Search = document.createElement('div')
Search.classList = 'row'
WishlistNav.children[0].classList.add('active');
const Search = document.createElement('div');
Search.classList = 'row';
Search.innerHTML = `
<div class="col-auto">
<select class="form-select" id="polyplus-itemwish-type" style="width: 150px;">
@ -78,73 +78,77 @@ if (window.location.pathname.split('/')[3] === "inventory") {
</label>
</div>
</div>
`
ItemGrid.parentElement.prepend(document.createElement('br'), ItemGrid.parentElement.children[0])
ItemGrid.parentElement.prepend(Search, ItemGrid.parentElement.children[0])
`;
ItemGrid.parentElement.prepend(document.createElement('br'), ItemGrid.parentElement.children[0]);
ItemGrid.parentElement.prepend(Search, ItemGrid.parentElement.children[0]);
let Type = document.getElementById('polyplus-itemwish-type')
let SearchBar = document.getElementById('polyplus-itemwish-searchbar')
let IsLimited = document.getElementById('polyplus-itemwish-isLimited')
let IsAvailable = document.getElementById('polyplus-itemwish-isAvailable')
let Type = document.getElementById('polyplus-itemwish-type');
let SearchBar = document.getElementById('polyplus-itemwish-searchbar');
let IsLimited = document.getElementById('polyplus-itemwish-isLimited');
let IsAvailable = document.getElementById('polyplus-itemwish-isAvailable');
Type.addEventListener('change', function () {
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
});
SearchBar.addEventListener('change', function () {
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
});
IsLimited.addEventListener('change', function () {
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
});
IsAvailable.addEventListener('change', function () {
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
});
chrome.storage.sync.get(['PolyPlus_ItemWishlist'], function (result) {
let Wishlist = result.PolyPlus_ItemWishlist || [];
console.log('wishlist: ', Wishlist)
Wishlist.forEach(element => {
let NewItemCard = document.createElement('div')
NewItemCard.classList = 'px-0'
console.log('wishlist: ', Wishlist);
Wishlist.forEach((element) => {
let NewItemCard = document.createElement('div');
NewItemCard.classList = 'px-0';
fetch('https://api.polytoria.com/v1/store/:id'.replace(':id', element))
.then(response => response.json())
.then(data => {
NewItemCard.innerHTML = ItemCardContents.replace(':ItemID', data.id).replace(':ItemThumbnail', data.thumbnail).replace(':ItemName', data.name).replace(':CreatorID', data.creator.id).replace(':CreatorName', data.creator.name)
.then((response) => response.json())
.then((data) => {
NewItemCard.innerHTML = ItemCardContents.replace(':ItemID', data.id)
.replace(':ItemThumbnail', data.thumbnail)
.replace(':ItemName', data.name)
.replace(':CreatorID', data.creator.id)
.replace(':CreatorName', data.creator.name);
if (data.isLimited === true) {
NewItemCard.innerHTML = NewItemCard.innerHTML.replace(':LimitedTag', '<div class="ribbon ribbon-limited ribbon-top-right"><span>Limited</span></div>')
NewItemCard.innerHTML = NewItemCard.innerHTML.replace(':LimitedTag', '<div class="ribbon ribbon-limited ribbon-top-right"><span>Limited</span></div>');
} else {
NewItemCard.innerHTML = NewItemCard.innerHTML.replace(':LimitedTag', '')
NewItemCard.innerHTML = NewItemCard.innerHTML.replace(':LimitedTag', '');
}
NewItemCard.setAttribute('data-id', data.id)
NewItemCard.setAttribute('data-name', data.name)
NewItemCard.setAttribute('data-type', data.type)
NewItemCard.setAttribute('data-creator', data.creator.name)
NewItemCard.setAttribute('data-limited', data.isLimited)
NewItemCard.setAttribute('data-id', data.id);
NewItemCard.setAttribute('data-name', data.name);
NewItemCard.setAttribute('data-type', data.type);
NewItemCard.setAttribute('data-creator', data.creator.name);
NewItemCard.setAttribute('data-limited', data.isLimited);
if (data.isLimited === false) {
NewItemCard.setAttribute('data-price', data.price)
NewItemCard.setAttribute('data-price', data.price);
}
ItemGrid.appendChild(NewItemCard)
ItemGrid.appendChild(NewItemCard);
NewItemCard.getElementsByClassName('polyplus-itemwish-removebtn')[0].addEventListener('click', function () {
let Index = Wishlist.indexOf(parseInt(NewItemCard.getAttribute('data-id')))
let Index = Wishlist.indexOf(parseInt(NewItemCard.getAttribute('data-id')));
if (Index === -1) {
NewItemCard.remove();
return
return;
} else {
Wishlist.splice(Index, 1)
console.log(Wishlist)
Wishlist.splice(Index, 1);
console.log(Wishlist);
NewItemCard.remove();
}
chrome.storage.sync.set({'PolyPlus_ItemWishlist': Wishlist, arrayOrder: true}, function() {
console.log('ItemWishlist successfully saved: ' + ItemWishlist)
chrome.storage.sync.set({PolyPlus_ItemWishlist: Wishlist, arrayOrder: true}, function () {
console.log('ItemWishlist successfully saved: ' + ItemWishlist);
});
});
})
.catch(error => {
.catch((error) => {
console.error('Error:', error);
});
});
@ -154,33 +158,41 @@ if (window.location.pathname.split('/')[3] === "inventory") {
}
function Update(type, query, isLimited, isAvailable) {
let ItemGrid = document.getElementsByClassName('itemgrid')[0]
let BrickBalance = parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).Bricks)
let ItemGrid = document.getElementsByClassName('itemgrid')[0];
let BrickBalance = parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).Bricks);
query = query.toLowerCase();
let Results = Array.from(ItemGrid.children)
let Results = Array.from(ItemGrid.children);
for (let i = 0; i < Results.length; i++) {
let Show = true
let Show = true;
console.log('type: ', type)
console.log('type: ', type);
if (!(type === 'any')) {
console.log('isn\'t any')
if (!(Results[i].getAttribute('data-type') === type)) {Show = false}
console.log("isn't any");
if (!(Results[i].getAttribute('data-type') === type)) {
Show = false;
}
}
if (!(Results[i].getAttribute('data-name').toLowerCase().startsWith(query))) {Show = false}
if (!Results[i].getAttribute('data-name').toLowerCase().startsWith(query)) {
Show = false;
}
if (isLimited === true) {
if (!(Results[i].getAttribute('data-limited') === 'true')) {Show = false}
if (!(Results[i].getAttribute('data-limited') === 'true')) {
Show = false;
}
}
if (isAvailable === true) {
if (!(parseInt(Results[i].getAttribute('data-price')) <= BrickBalance)) {Show = false}
if (!(parseInt(Results[i].getAttribute('data-price')) <= BrickBalance)) {
Show = false;
}
}
if (Show === true) {
Results[i].style.display = 'block'
Results[i].style.display = 'block';
} else {
Results[i].style.display = 'none'
Results[i].style.display = 'none';
}
}
}

View file

@ -1,6 +1,6 @@
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)')
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)');
var Settings;
var BestFriends;
@ -11,115 +11,117 @@ let Utilities;
if (UserID) {
(async () => {
UserID = (await (await fetch('https://api.polytoria.com/v1/users/')).json()).id
UserID = (await (await fetch('https://api.polytoria.com/v1/users/')).json()).id;
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings || {}
Settings = result.PolyPlus_Settings || {};
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
IRLPrice();
}
if (Settings.BestFriendsOn === true) {
BestFriends()
BestFriends();
}
if (Settings.OutfitCostOn === true) {
CalculateButton = document.createElement('small')
CalculateButton.classList = 'fw-normal text-success'
CalculateButton.style.letterSpacing = '0px'
CalculateButton.setAttribute('data-bs-toggle', 'tooltip')
CalculateButton.setAttribute('data-bs-title', 'Calculate this avatar\'s cost!')
CalculateButton.setAttribute('data-bs-placement', 'right')
CalculateButton = document.createElement('small');
CalculateButton.classList = 'fw-normal text-success';
CalculateButton.style.letterSpacing = '0px';
CalculateButton.setAttribute('data-bs-toggle', 'tooltip');
CalculateButton.setAttribute('data-bs-title', "Calculate this avatar's cost!");
CalculateButton.setAttribute('data-bs-placement', 'right');
CalculateButton.innerHTML = `
<a class="text-decoration-underline text-success" style="text-decoration-color: rgb(15, 132, 79) !important;">$ calculate</a>
`
AvatarHeading.appendChild(CalculateButton)
`;
AvatarHeading.appendChild(CalculateButton);
Utilities.InjectResource('registerTooltips')
Utilities.InjectResource('registerTooltips');
let Calculating = false
let Calculating = false;
CalculateButton.addEventListener('click', function () {
if (Calculating === false) {
Calculating = true
CalculateButton.innerText = '$ Calculating...'
OutfitCost()
Calculating = true;
CalculateButton.innerText = '$ Calculating...';
OutfitCost();
}
});
}
});
})();
const AvatarIFrame = document.querySelector('[src^="/ptstatic"]')
const DropdownMenu = document.getElementsByClassName('dropdown-menu dropdown-menu-right')[0]
const AvatarIFrame = document.querySelector('[src^="/ptstatic"]');
const DropdownMenu = document.getElementsByClassName('dropdown-menu dropdown-menu-right')[0];
const CopyItem = document.createElement('a')
CopyItem.classList = 'dropdown-item text-primary'
CopyItem.href = '#'
const CopyItem = document.createElement('a');
CopyItem.classList = 'dropdown-item text-primary';
CopyItem.href = '#';
CopyItem.innerHTML = `
<i class="fa-duotone fa-book"></i>
Copy 3D Avatar URL
`
DropdownMenu.appendChild(CopyItem)
`;
DropdownMenu.appendChild(CopyItem);
CopyItem.addEventListener('click', function () {
navigator.clipboard.writeText(AvatarIFrame.src)
navigator.clipboard
.writeText(AvatarIFrame.src)
.then(() => {
alert('Successfully copied 3D avatar URL!')
alert('Successfully copied 3D avatar URL!');
})
.catch(() => {
alert('Failure to copy 3D avatar URL.')
alert('Failure to copy 3D avatar URL.');
});
});
const ShareItem = document.createElement('a')
ShareItem.classList = 'dropdown-item text-warning'
ShareItem.href = '#'
const ShareItem = document.createElement('a');
ShareItem.classList = 'dropdown-item text-warning';
ShareItem.href = '#';
ShareItem.innerHTML = `
<i class="fa-duotone fa-book"></i>
Share your 3D Avatar URL!
`
DropdownMenu.appendChild(ShareItem)
`;
DropdownMenu.appendChild(ShareItem);
ShareItem.addEventListener('click', function () {
navigator.clipboard.writeText("Hey! Look at my Polytoria avatar in 3D [here](" + AvatarIFrame.src + ")!")
navigator.clipboard
.writeText('Hey! Look at my Polytoria avatar in 3D [here](' + AvatarIFrame.src + ')!')
.then(() => {
alert('Successfully copied sharable 3D avatar URL!')
alert('Successfully copied sharable 3D avatar URL!');
})
.catch(() => {
alert('Failure to copy sharable 3D avatar URL.')
alert('Failure to copy sharable 3D avatar URL.');
});
});
} else if (UserID && UserID[0] === "@") {
const Username = window.location.pathname.split('/')[2].substring(1)
} else if (UserID && UserID[0] === '@') {
const Username = window.location.pathname.split('/')[2].substring(1);
let Reference = new URLSearchParams(new URL(window.location.href).search)
let Reference = new URLSearchParams(new URL(window.location.href).search);
if (!Reference.has('ref')) {
Reference = ""
Reference = '';
}
fetch("https://api.polytoria.com/v1/users/find?username=" + Username)
.then(response => {
fetch('https://api.polytoria.com/v1/users/find?username=' + Username)
.then((response) => {
if (!response.ok) {
window.location.href = window.location.origin + decodeURIComponent(Reference.get('ref'))
window.location.href = window.location.origin + decodeURIComponent(Reference.get('ref'));
} else {
return response.json()
return response.json();
}
})
.then(data => {
window.location.href = "https://polytoria.com/users/" + data.id
.then((data) => {
window.location.href = 'https://polytoria.com/users/' + data.id;
})
.catch(error => {
console.log("An error occurred:", error);
.catch((error) => {
console.log('An error occurred:', error);
});
}
async function IRLPrice() {
const NetWorthElement = document.getElementsByClassName('float-end text-success')[0];
const IRLResult = await Utilities.CalculateIRL(NetWorthElement.innerText, Settings.IRLPriceWithCurrency.Currency)
NetWorthElement.innerHTML = NetWorthElement.innerHTML + '<div class="text-muted" style="font-size: 0.6rem;">(' + IRLResult.icon + IRLResult.result + ' ' + IRLResult.display + ')</div>'
const IRLResult = await Utilities.CalculateIRL(NetWorthElement.innerText, Settings.IRLPriceWithCurrency.Currency);
NetWorthElement.innerHTML = NetWorthElement.innerHTML + '<div class="text-muted" style="font-size: 0.6rem;">(' + IRLResult.icon + IRLResult.result + ' ' + IRLResult.display + ')</div>';
}
function BestFriends() {
@ -135,20 +137,22 @@ function BestFriends() {
FavoriteBtn.innerText = 'Best Friend';
}
} else {
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')'
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')';
}
if (UserID !== JSON.parse(window.localStorage.getItem('p+account_info')).ID && document.getElementById('add-friend-button').classList.contains('btn-success') === false) {
FavoriteBtn.addEventListener('click', function () {
Fav(UserID, FavoriteBtn);
});
} else {
FavoriteBtn.style.display = 'none'
FavoriteBtn.style.display = 'none';
}
document.querySelectorAll('.section-title.px-3.px-lg-0.mt-3')[0].appendChild(FavoriteBtn);
function Fav(UserID, btn) {
if (UserID === JSON.parse(window.localStorage.getItem('p+account_info')).ID) { return }
btn.setAttribute('disabled', 'true')
if (UserID === JSON.parse(window.localStorage.getItem('p+account_info')).ID) {
return;
}
btn.setAttribute('disabled', 'true');
chrome.storage.sync.get(['PolyPlus_BestFriends'], function (result) {
const BestFriends = result.PolyPlus_BestFriends || [];
@ -157,20 +161,20 @@ function BestFriends() {
if (index !== -1) {
// Number exists, remove it
BestFriends.splice(index, 1);
btn.innerText = "Best Friend"
btn.innerText = 'Best Friend';
console.log('Number', parseInt(UserID), 'removed from BestFriends');
} else {
// Number doesn't exist, add it
BestFriends.push(parseInt(UserID));
btn.innerText = "Remove Best Friend Status"
btn.innerText = 'Remove Best Friend Status';
console.log('Number', parseInt(UserID), 'added to BestFriends');
}
chrome.storage.sync.set({ 'PolyPlus_BestFriends': BestFriends, arrayOrder: true }, function() {
chrome.storage.sync.set({PolyPlus_BestFriends: BestFriends, arrayOrder: true}, function () {
console.log('BestFriends saved successfully!');
setTimeout(function () {
btn.removeAttribute('disabled')
}, 1500)
btn.removeAttribute('disabled');
}, 1500);
});
});
}
@ -183,23 +187,23 @@ function BestFriends() {
if (!(BestFriends.length === Utilities.Limits.BestFriends)) {
if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID))) {
FavoriteBtn.innerText = 'Remove Best Friend Status'
FavoriteBtn.innerText = 'Remove Best Friend Status';
} else {
FavoriteBtn.innerText = 'Best Friend'
FavoriteBtn.innerText = 'Best Friend';
}
} else {
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')'
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')';
}
});
}
});
function ClearBestFriends() {
chrome.storage.sync.set({ 'PolyPlus_BestFriends': {"BestFriends": []}, arrayOrder: true }, function() {
chrome.storage.sync.set({PolyPlus_BestFriends: {BestFriends: []}, arrayOrder: true}, function () {
console.log('BestFriends saved successfully!');
setTimeout(function () {
btn.removeAttribute('disabled')
}, 1500)
btn.removeAttribute('disabled');
}, 1500);
});
}
}
@ -210,38 +214,40 @@ async function OutfitCost() {
Collectibles: 0,
Offsale: 0,
HasProfileTheme: false
}
};
for (let item of AvatarRow.children) {
const ItemID = item.getElementsByTagName('a')[0].href.split('/')[4]
const ItemID = item.getElementsByTagName('a')[0].href.split('/')[4];
await fetch('https://api.polytoria.com/v1/store/' + ItemID)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
let Price = data.price
.then((data) => {
let Price = data.price;
if (data.isLimited === true) {
AvatarCost.Collectibles += 1
Price = data.averagePrice
AvatarCost.Collectibles += 1;
Price = data.averagePrice;
} else if (data.sales === 0) {
AvatarCost.Offsale += 1
Price = 0
AvatarCost.Offsale += 1;
Price = 0;
} else if (data.type === 'profileTheme') {
AvatarCost.HasProfileTheme = true
Price = 0
AvatarCost.HasProfileTheme = true;
Price = 0;
}
AvatarCost.Total += Price
AvatarCost.Total += Price;
})
.catch(error => {console.log(error)});
.catch((error) => {
console.log(error);
});
}
const ResultText = document.createElement('small')
ResultText.classList = 'fw-normal text-success'
ResultText.style.letterSpacing = '0px'
ResultText.innerHTML = `(<i class="pi pi-brick mx-1"></i> ${ (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' : '' })`
const ResultText = document.createElement('small');
ResultText.classList = 'fw-normal text-success';
ResultText.style.letterSpacing = '0px';
ResultText.innerHTML = `(<i class="pi pi-brick mx-1"></i> ${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)
CalculateButton.remove();
AvatarHeading.appendChild(ResultText);
}

View file

@ -1,15 +1,15 @@
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
if (result.PolyPlus_Settings.MoreSearchFiltersOn === true) {
const BlockedUsersCard = document.getElementsByClassName('card-body')[1]
const InputGroup = document.createElement('div')
InputGroup.classList = 'input-group mb-2'
const BlockedUsersCard = document.getElementsByClassName('card-body')[1];
const InputGroup = document.createElement('div');
InputGroup.classList = 'input-group mb-2';
InputGroup.innerHTML = `
<input id="blocked-users-search" type="text" class="form-control bg-dark" placeholder="Search blocked users...">
<button id="blocked-users-confirm" class="btn btn-secondary"><i class="fad fa-search"></i></button>
`
BlockedUsersCard.insertBefore(InputGroup, BlockedUsersCard.children[0])
const SearchBar = document.getElementById('blocked-users-search')
const ConfirmBtn = document.getElementById('blocked-users-confirm')
`;
BlockedUsersCard.insertBefore(InputGroup, BlockedUsersCard.children[0]);
const SearchBar = document.getElementById('blocked-users-search');
const ConfirmBtn = document.getElementById('blocked-users-confirm');
ConfirmBtn.addEventListener('click', function () {
SearchBlockedUsers(SearchBar.value);
@ -20,9 +20,9 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
for (let i = 1; i < BlockedUsersCard.children.length; i++) {
let Username = BlockedUsersCard.children[i].getElementsByTagName('h5')[0].innerText.toLowerCase();
if (Username.includes(query)) {
BlockedUsersCard.children[i].style.display = 'block'
BlockedUsersCard.children[i].style.display = 'block';
} else {
BlockedUsersCard.children[i].style.display = 'none'
BlockedUsersCard.children[i].style.display = 'none';
}
}
}

View file

@ -1,109 +1,108 @@
var SelectedTrades = []
var SelectedTrades = [];
let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement
let Text = document.createElement('p')
Text.classList = 'mx-auto'
Text.style.textAlign = 'center'
Text.style.fontSize = '1.3rem'
let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement;
let Text = document.createElement('p');
Text.classList = 'mx-auto';
Text.style.textAlign = 'center';
Text.style.fontSize = '1.3rem';
Text.innerHTML = `
<span>0</span> trades selected!
<br>
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
<button id="cancelSelectionBtn" class="btn btn-danger">Cancel Selected Trades</button>
`
Parent.insertBefore(Text, Parent.children[0])
`;
Parent.insertBefore(Text, Parent.children[0]);
let Text_Span = Text.querySelector('span');
let Text_View = document.getElementById('viewSelectionBtn');
let Text_Clear = document.getElementById('clearSelectionBtn');
let Text_Cancel = document.getElementById('cancelSelectionBtn');
var ConfirmCancel = 0
var ConfirmCancel = 0;
Text_View.addEventListener('click', function () {});
Text_Clear.addEventListener('click', function () {
SelectedTrades = []
SelectedTrades = [];
UpdateCheckboxes();
Text_Span.innerText = SelectedTrades.length
Text_Span.innerText = SelectedTrades.length;
});
Text_Cancel.addEventListener('click', function () {
ConfirmCancel = ConfirmCancel + 1
ConfirmCancel = ConfirmCancel + 1;
switch (ConfirmCancel) {
case 0:
Text_Cancel.innerText = 'Cancel Selected Trades'
break
Text_Cancel.innerText = 'Cancel Selected Trades';
break;
case 1:
Text_Cancel.innerText = 'Are you sure?'
break
Text_Cancel.innerText = 'Are you sure?';
break;
case 2:
let Success = true
let Success = true;
for (let i = 0; i < SelectedTrades.length; i++) {
setTimeout(function () {}, 110)
console.log(SelectedTrades[i])
setTimeout(function () {}, 110);
console.log(SelectedTrades[i]);
fetch('https://polytoria.com/api/trade/decline', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
},
body: JSON.stringify({ id: SelectedTrades[i] }),
})
.catch(error => {
body: JSON.stringify({id: SelectedTrades[i]})
}).catch((error) => {
// Handle any errors
console.error('Error:', error);
Success = false
Success = false;
});
}
SelectedTrades = []
SelectedTrades = [];
UpdateCheckboxes();
Text_Cancel.innerText = 'Cancel Selected Trades'
ConfirmCancel = 0
break
Text_Cancel.innerText = 'Cancel Selected Trades';
ConfirmCancel = 0;
break;
}
});
LoadCheckBoxes();
function LoadCheckBoxes() {
Array.from(document.getElementsByClassName('card-inbox')).forEach(element => {
let ViewBtn = element.querySelector('a.btn.btn-primary')
let TradeID = parseInt(ViewBtn.getAttribute('href').split('/')[3])
var NewCheckBox = document.createElement('button')
NewCheckBox.classList = 'polyplus-multicanceltr-checkbox'
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem; margin-left: 10px;')
var Index = SelectedTrades.indexOf(TradeID)
Array.from(document.getElementsByClassName('card-inbox')).forEach((element) => {
let ViewBtn = element.querySelector('a.btn.btn-primary');
let TradeID = parseInt(ViewBtn.getAttribute('href').split('/')[3]);
var NewCheckBox = document.createElement('button');
NewCheckBox.classList = 'polyplus-multicanceltr-checkbox';
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem; margin-left: 10px;');
var Index = SelectedTrades.indexOf(TradeID);
if (Index !== -1) {
NewCheckBox.style.borderColor = 'lime'
NewCheckBox.style.borderColor = 'lime';
}
ViewBtn.parentElement.appendChild(NewCheckBox)
ViewBtn.parentElement.appendChild(NewCheckBox);
NewCheckBox.addEventListener('click', function () {
var Index = SelectedTrades.indexOf(TradeID)
var Index = SelectedTrades.indexOf(TradeID);
if (Index === -1) {
SelectedTrades.push(TradeID)
NewCheckBox.style.borderColor = 'lime'
SelectedTrades.push(TradeID);
NewCheckBox.style.borderColor = 'lime';
} else {
SelectedTrades.splice(Index, 1)
NewCheckBox.style.borderColor = '#393939'
SelectedTrades.splice(Index, 1);
NewCheckBox.style.borderColor = '#393939';
}
Text_Span.innerText = SelectedTrades.length
Text_Span.innerText = SelectedTrades.length;
UpdateCheckboxes();
});
});
}
function UpdateCheckboxes() {
document.querySelectorAll('.polyplus-multicanceltr-checkbox').forEach(element => {
let Parent = element.parentElement
let ViewBtn = Parent.querySelector('a.btn.btn-primary')
document.querySelectorAll('.polyplus-multicanceltr-checkbox').forEach((element) => {
let Parent = element.parentElement;
let ViewBtn = Parent.querySelector('a.btn.btn-primary');
if (element.getAttribute('disabled')) {
element.removeAttribute('disabled')
element.removeAttribute('disabled');
}
if (SelectedTrades.IndexOf(ViewBtn.getAttribute('data-user-id')) === -1) {
element.style.borderColor = '#393939'
element.style.borderColor = '#393939';
} else {
element.style.borderColor = 'lime'
element.style.borderColor = 'lime';
if (SelectedTrades.length >= 10) {
element.setAttribute('disabled', true)
element.setAttribute('disabled', true);
}
}
})
});
}

View file

@ -10,11 +10,11 @@ LoadFile(chrome.runtime.getURL('resources/currencies.json'), function(text){
let Utilities;
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
})();
let Nav = document.getElementsByClassName('nav-pills')[0]
let DIV = document.createElement('div')
let Nav = document.getElementsByClassName('nav-pills')[0];
let DIV = document.createElement('div');
DIV.innerHTML = `
<input id="polyplus-brickconverter-input" type="number" class="form-control bg-dark mb-2" placeholder="How many Bricks?">
<input id="polyplus-brickconverter-output" type="text" class="form-control bg-dark mb-2" placeholder="Result" disabled>
@ -37,24 +37,24 @@ DIV.innerHTML = `
<option value="5">d</option>
</select>
-->
`
Nav.appendChild(document.createElement('hr'))
Nav.appendChild(DIV)
`;
Nav.appendChild(document.createElement('hr'));
Nav.appendChild(DIV);
let Input = document.getElementById('polyplus-brickconverter-input')
let Output = document.getElementById('polyplus-brickconverter-output')
let Type = document.getElementById('polyplus-brickconverter-type')
let Input = document.getElementById('polyplus-brickconverter-input');
let Output = document.getElementById('polyplus-brickconverter-output');
let Type = document.getElementById('polyplus-brickconverter-type');
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Type.selectedIndex = result.PolyPlus_Settings.IRLPriceWithCurrency.Currency || 0
Type.selectedIndex = result.PolyPlus_Settings.IRLPriceWithCurrency.Currency || 0;
});
//let Package = document.getElementById('polyplus-brickconverter-package')
Input.addEventListener('input', function () {
Update()
Update();
});
Type.addEventListener('change', function () {
Update()
Update();
});
/*
@ -64,17 +64,19 @@ Package.addEventListener('change', function(){
*/
async function Update() {
if (Input.value === "") {
Output.value = ''
return
if (Input.value === '') {
Output.value = '';
return;
}
const IRLResult = await Utilities.CalculateIRL(Input.value, Type.selectedIndex)
Output.value = "$" + IRLResult.result + " " + IRLResult.display
const IRLResult = await Utilities.CalculateIRL(Input.value, Type.selectedIndex);
Output.value = '$' + IRLResult.result + ' ' + IRLResult.display;
}
function LoadFile(path, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function () { return callback(this.responseText); }
xhr.open("GET", path, true);
xhr.onload = function () {
return callback(this.responseText);
};
xhr.open('GET', path, true);
xhr.send();
}

View file

@ -1,5 +1,5 @@
const Manifest = chrome.runtime.getManifest()
const SettingsURL = chrome.runtime.getURL('settings.html')
const Manifest = chrome.runtime.getManifest();
const SettingsURL = chrome.runtime.getURL('settings.html');
/*
ON INSTALL:
@ -16,7 +16,7 @@ chrome.action.onClicked.addListener((tab) => {
// REGISTER AN ALARM FOR DAILY UPDATE CHECK
chrome.alarms.create('PolyPlus-UpdateCheck', {
when: Date.now() + (GetNext12PM())
when: Date.now() + GetNext12PM()
});
function GetNext12PM() {
@ -32,50 +32,55 @@ function GetNext12PM() {
// HANDLE ALARMS FIRING
chrome.alarms.onAlarm.addListener(function (alarm) {
if (alarm.name === 'PolyPlus-UpdateCheck') {
RunUpdateNotifier()
RunUpdateNotifier();
}
});
function RunUpdateNotifier() {
chrome.storage.local.get(["PolyPlus_LiveVersion", "PolyPlus_OutOfDate", "PolyPlus_SkipUpdate"], function(result){
const OutOfDate = result.PolyPlus_OutOfDate || false
const SkipUpdate = result.PolyPlus_SkipUpdate || null
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version
chrome.storage.local.get(['PolyPlus_LiveVersion', 'PolyPlus_OutOfDate', 'PolyPlus_SkipUpdate'], function (result) {
const OutOfDate = result.PolyPlus_OutOfDate || false;
const SkipUpdate = result.PolyPlus_SkipUpdate || null;
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version;
if (OutOfDate !== true && SkipUpdate !== LiveVersion) {
fetch('https://polyplus.vercel.app/data/version.json')
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
chrome.storage.local.set({'PolyPlus_LiveVersion': data.version}, function(){
console.log('Cached live version')
})
if (data.version > Manifest.version) {
chrome.storage.local.set({'PolyPlus_OutOfDate': true, 'PolyPlus_ReleaseNotes': data.releaseNotes}, function(){
console.log('Cached update notifier result')
.then((data) => {
chrome.storage.local.set({PolyPlus_LiveVersion: data.version}, function () {
console.log('Cached live version');
});
chrome.notifications.create("", {
type: "basic",
iconUrl: chrome.runtime.getURL("icon.png"),
title: "New Update Available",
message: "A new update is available for Poly+! (v" + data.version + ")"
}, function(notificationID) {
if (data.version > Manifest.version) {
chrome.storage.local.set({PolyPlus_OutOfDate: true, PolyPlus_ReleaseNotes: data.releaseNotes}, function () {
console.log('Cached update notifier result');
});
chrome.notifications.create(
'',
{
type: 'basic',
iconUrl: chrome.runtime.getURL('icon.png'),
title: 'New Update Available',
message: 'A new update is available for Poly+! (v' + data.version + ')'
},
function (notificationID) {
chrome.notifications.onClicked.addListener(function (id) {
if (id === notificationID) {
chrome.tabs.create({url: 'https://github.com/IndexingGitHub/PolyPlus/releases', active: true})
chrome.notifications.clear(notificationID)
chrome.tabs.create({url: 'https://github.com/IndexingGitHub/PolyPlus/releases', active: true});
chrome.notifications.clear(notificationID);
}
});
}
})
})
chrome.action.setBadgeBackgroundColor(
{color: 'red'},
() => { /* ... */ },
);
chrome.action.setBadgeBackgroundColor({color: 'red'}, () => {
/* ... */
});
}
})
.catch(error => {console.log(error)})
.catch((error) => {
console.log(error);
});
}
});
}
@ -85,9 +90,7 @@ chrome.contextMenus.removeAll(function() {
title: 'Run Update Notifier',
id: 'PolyPlus-RunUpdateNotifier',
contexts: ['all'],
documentUrlPatterns: [
"https://polytoria.com/my/settings/polyplus-debug",
]
documentUrlPatterns: ['https://polytoria.com/my/settings/polyplus-debug']
});
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
@ -95,15 +98,8 @@ chrome.contextMenus.removeAll(function() {
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/**"
]
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
@ -111,57 +107,50 @@ chrome.contextMenus.removeAll(function() {
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/**"
]
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) {
if (info.menuItemId === 'PolyPlus-CopyID') {
let ID = parseInt(info.linkUrl.split('/')[4])
let ID = parseInt(info.linkUrl.split('/')[4]);
chrome.scripting
.executeScript({
target: {tabId: tab.id},
func: CopyAssetID,
args: [ID]
})
.then(() => console.log("Copied ID!"));
.then(() => console.log('Copied ID!'));
}
if (info.menuItemId === 'PolyPlus-CopyAvatarHash') {
let Hash = new URL(info.srcUrl).pathname.split('/')[3].replace('-icon', '').replace('.png', '')
let Hash = new URL(info.srcUrl).pathname.split('/')[3].replace('-icon', '').replace('.png', '');
chrome.scripting
.executeScript({
target: {tabId: tab.id},
func: CopyAvatarHash,
args: [Hash]
})
.then(() => console.log("Copied ID!"));
.then(() => console.log('Copied ID!'));
}
if (info.menuItemId === 'PolyPlus-RunUpdateNotifier') {
RunUpdateNotifier()
RunUpdateNotifier();
}
});
chrome.runtime.onMessage.addListener(function (message, sender) {
console.log('hi')
message = message.message || ''
console.log(message)
console.log('hi');
message = message.message || '';
console.log(message);
if (message === 'tooltip') {
console.log('is about tooltip')
chrome.scripting
.executeScript({
console.log('is about tooltip');
chrome.scripting.executeScript({
target: {tabId: sender.tab.id},
func: UpdateTooltips
})
});
}
});
@ -202,10 +191,10 @@ function CopyAssetID(id) {
navigator.clipboard
.writeText(id)
.then(() => {
alert('Successfully copied ID!')
alert('Successfully copied ID!');
})
.catch(() => {
alert('Failure to copy ID.')
alert('Failure to copy ID.');
});
}
@ -213,18 +202,18 @@ function CopyAvatarHash(hash) {
navigator.clipboard
.writeText(hash)
.then(() => {
alert('Successfully copied avatar hash!')
alert('Successfully copied avatar hash!');
})
.catch(() => {
alert('Failure to copy avatar hash.')
alert('Failure to copy avatar hash.');
});
}
function UpdateTooltips() {
const Script = document.createElement('script')
const Script = document.createElement('script');
Script.innerHTML = `
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
`
document.body.appendChild(Script)
`;
document.body.appendChild(Script);
}

View file

@ -3,9 +3,9 @@
Accessable at /my/settings/polyplus#dev
*/
if (window.location.pathname.split('/')[3] === "polyplus" && window.location.hash === '#dev') {
document.title = 'Poly+ Debug - Polytoria'
const Version = chrome.runtime.getManifest().version
if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.hash === '#dev') {
document.title = 'Poly+ Debug - Polytoria';
const Version = chrome.runtime.getManifest().version;
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#main-content .container').innerHTML = `
@ -101,133 +101,141 @@ if (window.location.pathname.split('/')[3] === "polyplus" && window.location.has
</div>
</div>
</div>
`
`;
const CheckForUpdatesButton = document.getElementById('check-for-updates')
const CheckForUpdatesButton = document.getElementById('check-for-updates');
function CheckForUpdates() {
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates)
CheckForUpdatesButton.disabled = true
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates);
CheckForUpdatesButton.disabled = true;
fetch('https://polyplus.vercel.app/data/version.json')
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
.then((data) => {
if (data.version === Version || Math.floor((data.version - Version) * 10) === 0) {
CheckForUpdatesButton.innerText = 'No updates available'
CheckForUpdatesButton.innerText = 'No updates available';
} else {
CheckForUpdatesButton.innerText = Math.floor((data.version - Version) * 10) + ' updates available'
CheckForUpdatesButton.innerText = Math.floor((data.version - Version) * 10) + ' updates available';
}
})
.catch(error => {console.log(error)});
.catch((error) => {
console.log(error);
});
}
CheckForUpdatesButton.addEventListener('click', CheckForUpdates);
document.getElementById('edit-setting').addEventListener('click', function () {
const EditSettingName = document.getElementById('edit-setting-name')
const EditSettingValue = document.getElementById('edit-setting-value')
const EditSettingName = document.getElementById('edit-setting-name');
const EditSettingValue = document.getElementById('edit-setting-value');
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
result = result.PolyPlus_Settings
result = result.PolyPlus_Settings;
let NewValue = EditSettingValue.value
let NewValue = EditSettingValue.value;
switch (NewValue) {
case 'true':
NewValue = true
break
NewValue = true;
break;
case 'false':
NewValue = false
break
NewValue = false;
break;
case 'null':
NewValue = null
break
NewValue = null;
break;
case 'undefined':
NewValue = undefined
break
NewValue = undefined;
break;
case parseInt(NewValue):
NewValue = parseInt(NewValue)
break
NewValue = parseInt(NewValue);
break;
}
result[EditSettingName.value] = NewValue
result[EditSettingName.value] = NewValue;
chrome.storage.sync.set({ 'PolyPlus_Settings': result }, function() {
alert('Successfully set: "' + EditSettingName.value + '" to ' + NewValue)
chrome.storage.sync.set({PolyPlus_Settings: result}, function () {
alert('Successfully set: "' + EditSettingName.value + '" to ' + NewValue);
});
});
});
document.getElementById('reset-settings').addEventListener('click', async function () {
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'))
Utilities = Utilities.default
chrome.storage.sync.set({ 'PolyPlus_Settings': Utilities.DefaultSettings }, function() {
alert('Successfully reset settings to their defaults!')
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default;
chrome.storage.sync.set({PolyPlus_Settings: Utilities.DefaultSettings}, function () {
alert('Successfully reset settings to their defaults!');
});
});
document.getElementById('example-pinnedgames').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': [6012, 3857, 2537] }, function() {
alert('Successfully loaded example for Pinned Games!')
chrome.storage.sync.set({PolyPlus_PinnedGames: [6012, 3857, 2537]}, function () {
alert('Successfully loaded example for Pinned Games!');
});
});
document.getElementById('example-bestfriends').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_BestFriends': [1, 2, 3] }, function() {
alert('Successfully loaded example for Best Friends!')
chrome.storage.sync.set({PolyPlus_BestFriends: [1, 2, 3]}, function () {
alert('Successfully loaded example for Best Friends!');
});
});
document.getElementById('example-itemwishlist').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_ItemWishlist': [31495, 31493, 31492] }, function() {
alert('Successfully loaded example for Item Wishlist!')
chrome.storage.sync.set({PolyPlus_ItemWishlist: [31495, 31493, 31492]}, function () {
alert('Successfully loaded example for Item Wishlist!');
});
});
document.getElementById('clear-pinnedgames').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': [] }, function() {
alert('Successfully cleared Pinned Games!')
chrome.storage.sync.set({PolyPlus_PinnedGames: []}, function () {
alert('Successfully cleared Pinned Games!');
});
});
document.getElementById('clear-bestfriends').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_BestFriends': [] }, function() {
alert('Successfully cleared Best Friends!')
chrome.storage.sync.set({PolyPlus_BestFriends: []}, function () {
alert('Successfully cleared Best Friends!');
});
});
document.getElementById('clear-itemwishlist').addEventListener('click', function () {
chrome.storage.sync.set({ 'PolyPlus_ItemWishlist': [] }, function() {
alert('Successfully cleared Item Wishlist!')
chrome.storage.sync.set({PolyPlus_ItemWishlist: []}, function () {
alert('Successfully cleared Item Wishlist!');
});
});
document.getElementById('delete-sync').addEventListener('click', function () {
if (confirm("Are you sure you'd like to delete all sync data associated with the extension?") === false) { return }
if (confirm("Are you sure you'd like to delete all sync data associated with the extension?") === false) {
return;
}
chrome.storage.sync.clear(function () {
alert('Successfully deleted all sync data associated with the extension!')
alert('Successfully deleted all sync data associated with the extension!');
});
});
document.getElementById('delete-local').addEventListener('click', function () {
if (confirm("Are you sure you'd like to delete all local data associated with the extension?") === false) { return }
if (confirm("Are you sure you'd like to delete all local data associated with the extension?") === false) {
return;
}
chrome.storage.local.clear(function () {
alert('Successfully deleted all local data associated with the extension!')
alert('Successfully deleted all local data associated with the extension!');
});
});
document.getElementById('delete-all-data').addEventListener('click', function () {
if (confirm("Are you sure you'd like to delete all sync and local data associated with the extension?") === false) { return }
if (confirm("Are you sure you'd like to delete all sync and local data associated with the extension?") === false) {
return;
}
chrome.storage.sync.clear(function () {
alert('Successfully deleted all sync data associated with the extension!')
alert('Successfully deleted all sync data associated with the extension!');
});
chrome.storage.local.clear(function () {
alert('Successfully deleted all local data associated with the extension!')
alert('Successfully deleted all local data associated with the extension!');
});
});
chrome.storage.sync.getBytesInUse(["PolyPlus_Settings", "PolyPlus_PinnedGames", "PolyPlus_BestFriends", "PolyPlus_ItemWishlist"], function(bytes){
document.getElementById('data-size').innerText = bytes.toLocaleString()
chrome.storage.sync.getBytesInUse(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_BestFriends', 'PolyPlus_ItemWishlist'], function (bytes) {
document.getElementById('data-size').innerText = bytes.toLocaleString();
});
});
})
}

View file

@ -3,25 +3,25 @@ let Theme = ``;
(async () => {
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
// Merge settings and expected settings to make sure all keys exist
const RawSettings = result.PolyPlus_Settings
const RawSettings = result.PolyPlus_Settings;
Settings = MergeObjects(RawSettings || Utilities.DefaultSettings, Utilities.DefaultSettings);
// If theme exists, create a style element to represent it
if (Settings.ThemeCreator.Enabled && Settings.ThemeCreator.Enabled === true) {
switch (Settings.ThemeCreator.BGImageSize) {
case 0:
Settings.ThemeCreator.BGImageSize = 'fit'
break
Settings.ThemeCreator.BGImageSize = 'fit';
break;
case 1:
Settings.ThemeCreator.BGImageSize = 'cover'
break
Settings.ThemeCreator.BGImageSize = 'cover';
break;
case 2:
Settings.ThemeCreator.BGImageSize = 'contain'
break
Settings.ThemeCreator.BGImageSize = 'contain';
break;
}
Theme += `
:root {
@ -109,7 +109,7 @@ let Theme = ``;
.nav-sidebar-text {
color: var(--polyplus-sidebaritemlabelcolor) !important;
}
`
`;
}
});
@ -119,7 +119,7 @@ let Theme = ``;
div[style^="max-width: 728px;"]:has(.text-center a[href^="/ads/"]) {
display: none;
}
`
`;
}
if (Settings.HideUserAdsOn.Rectangles === true) {
@ -127,7 +127,7 @@ let Theme = ``;
div[style^="max-width: 300px;"]:has(.text-center a[href^="/ads/"]) {
display: none;
}
`
`;
}
}
@ -136,42 +136,42 @@ let Theme = ``;
.notif-nav .notif-sidebar {
display: none;
}
`
`;
}
// 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 = URL.createObjectURL(ThemeBlob)
document.head.innerHTML += `<link href="${ThemeURL}" rel="stylesheet" type="text/css">`
const ThemeBlob = new Blob([Theme], {type: 'text/css'});
const ThemeURL = URL.createObjectURL(ThemeBlob);
document.head.innerHTML += `<link href="${ThemeURL}" rel="stylesheet" type="text/css">`;
document.addEventListener('DOMContentLoaded', async function () {
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
return
return;
}
Utilities.InjectResource('getUserDetails')
document.body.setAttribute('data-URL', window.location.pathname)
Utilities.InjectResource('getUserDetails');
document.body.setAttribute('data-URL', window.location.pathname);
const UserData = JSON.parse(window.localStorage.getItem('p+account_info'))
const UserData = JSON.parse(window.localStorage.getItem('p+account_info'));
if (Settings.IRLPriceWithCurrency.Enabled === true) {
const IRLResult = await Utilities.CalculateIRL(document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g,''), Settings.IRLPriceWithCurrency.Currency)
const IRLResult = await Utilities.CalculateIRL(document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g, ''), Settings.IRLPriceWithCurrency.Currency);
// Desktop
document.querySelector('.text-success .brickBalanceCount').innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`
document.querySelector('.text-success .brickBalanceCount').innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`;
// Mobile
document.querySelector('.text-success .brickBalanceCont').innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`
document.querySelector('.text-success .brickBalanceCont').innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`;
//document.querySelector('.text-success .brickBalanceCont').innerHTML += `<div class="text-muted" style="font-size: 0.6rem;text-align: right;">(${IRLResult.icon}${IRLResult.result} ${IRLResult.display})</div>`
}
if (Settings.ModifyNavOn && Settings.ModifyNavOn === true) {
let NavbarItems = document.querySelectorAll('.navbar-nav.me-auto a.nav-link[href]')
let Needed = [NavbarItems[11],NavbarItems[12],NavbarItems[13],NavbarItems[14],NavbarItems[15]]
let NavbarItems = document.querySelectorAll('.navbar-nav.me-auto a.nav-link[href]');
let Needed = [NavbarItems[11], NavbarItems[12], NavbarItems[13], NavbarItems[14], NavbarItems[15]];
for (let i = 0; i < Settings.ModifyNav.length; i++) {
if (Settings.ModifyNav[i].Label != null) {
console.log(Needed[i], Needed[i].children[1])
Needed[i].children[1].innerText = Settings.ModifyNav[i].Label
Needed[i].href = Settings.ModifyNav[i].Link
console.log(Needed[i], Needed[i].children[1]);
Needed[i].children[1].innerText = Settings.ModifyNav[i].Label;
Needed[i].href = Settings.ModifyNav[i].Link;
}
}
}
@ -183,7 +183,9 @@ let Theme = ``;
*/
if (Settings.HideNotifBadgesOn === true) {
document.getElementsByClassName('notif-nav notif-sidebar').forEach(element => {element.remove();});
document.getElementsByClassName('notif-nav notif-sidebar').forEach((element) => {
element.remove();
});
}
});
})();

View file

@ -1,34 +1,34 @@
setTimeout(function () {}, 100)
setTimeout(function () {}, 100);
var Settings;
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings;
if (!(Settings.MoreSearchFiltersOn === true)) {
return
return;
}
let Form = document.querySelector('form[action="/forum/search"]')
let SearchBtn = document.querySelector('button[type="submit"]')
let CreatedByFilter = document.createElement('div')
CreatedByFilter.classList = 'input-group mt-2'
let Form = document.querySelector('form[action="/forum/search"]');
let SearchBtn = document.querySelector('button[type="submit"]');
let CreatedByFilter = document.createElement('div');
CreatedByFilter.classList = 'input-group mt-2';
CreatedByFilter.innerHTML = `
<div class="form-check">
<input class="form-check-input" type="checkbox">
<label class="form-check-label" for="createdBy">Created by <input type="text" class="form-control" placeholder="willemsteller" id="createdBy" name="createdBy"></label>
</div>
`
console.log(SearchBtn)
Form.insertBefore(CreatedByFilter, SearchBtn.parentElement)
let CreatedByFilter_Checkbox = CreatedByFilter.querySelector('input[type="checkbox"]')
let CreatedByFilter_Input = CreatedByFilter.querySelector('input[type="text"]')
let CreatedByValue = GetURLParameter("createdBy")
console.log(CreatedByValue)
`;
console.log(SearchBtn);
Form.insertBefore(CreatedByFilter, SearchBtn.parentElement);
let CreatedByFilter_Checkbox = CreatedByFilter.querySelector('input[type="checkbox"]');
let CreatedByFilter_Input = CreatedByFilter.querySelector('input[type="text"]');
let CreatedByValue = GetURLParameter('createdBy');
console.log(CreatedByValue);
if (CreatedByValue) {
CreatedByFilter_Checkbox.setAttribute('checked', true)
CreatedByFilter_Input.setAttribute('value', CreatedByValue)
CreatedByFilter_Input.removeAttribute('disabled')
document.querySelectorAll('.forum-entry').forEach(element => {
console.log(element.querySelectorAll('a[href^="/users/"]')[1].innerText)
CreatedByFilter_Checkbox.setAttribute('checked', true);
CreatedByFilter_Input.setAttribute('value', CreatedByValue);
CreatedByFilter_Input.removeAttribute('disabled');
document.querySelectorAll('.forum-entry').forEach((element) => {
console.log(element.querySelectorAll('a[href^="/users/"]')[1].innerText);
if (!(element.querySelectorAll('a[href^="/users/"]')[1].innerText === CreatedByValue)) {
element.remove();
}

View file

@ -1,51 +1,51 @@
const ForumText = document.querySelectorAll('p:not(.text-muted):not(.mb-0)')
const ForumText = document.querySelectorAll('p:not(.text-muted):not(.mb-0)');
var Settings = []
var Settings = [];
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings || {
ForumMentsOn: false,
ForumUnixStampsOn: false
}
};
if (Settings.ForumMentsOn === true) {
ForumMentions()
ForumMentions();
}
if (Settings.ForumUnixStampsOn === true) {
ForumUnixTimestamps()
ForumUnixTimestamps();
}
});
function ForumMentions() {
const Regex = /@([\w.]+)/g
const Regex = /@([\w.]+)/g;
for (let text of ForumText) {
let FormattedText = text.innerHTML
let FormattedText = text.innerHTML;
let match;
while ((match = Regex.exec(text.innerText)) !== null) {
const Username = match[0].substring(1)
FormattedText = FormattedText.replaceAll(match[0], `<a href="/users/@${Username}?ref=${encodeURIComponent(window.location.pathname)}" class="polyplus-mention">${match[0]}</a>`)
const Username = match[0].substring(1);
FormattedText = FormattedText.replaceAll(match[0], `<a href="/users/@${Username}?ref=${encodeURIComponent(window.location.pathname)}" class="polyplus-mention">${match[0]}</a>`);
}
text.innerHTML = FormattedText
text.innerHTML = FormattedText;
}
}
function ForumUnixTimestamps() {
const Regex = /&lt;t:[A-Za-z0-9]+&gt;/i
const Regex = /&lt;t:[A-Za-z0-9]+&gt;/i;
for (let text of ForumText) {
let FormattedText = text.innerHTML
let FormattedText = text.innerHTML;
let match;
while ((match = Regex.exec(FormattedText)) !== null) {
const Timestamp = new Date(match[0].substring(6, match[0].length - 4) * 1000)
const Months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
const Timestamp = new Date(match[0].substring(6, match[0].length - 4) * 1000);
const Months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const Distance = new Intl.RelativeTimeFormat({numeric: 'auto', style: 'short'}).format(Math.floor((Timestamp - new Date()) / (60 * 1000)), 'day')
const Result = `<code style="color: orange;">${Months[Timestamp.getMonth()]} ${Timestamp.getDate()}, ${Timestamp.getFullYear()} (${["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"][Timestamp.getDay()-1]}) at ${Timestamp.getHours()-12}:${String(Timestamp.getMinutes()).padStart(2, "0")} (${Distance})</code>`
FormattedText = FormattedText.replaceAll(match[0], Result)
console.log(FormattedText)
const Distance = new Intl.RelativeTimeFormat({numeric: 'auto', style: 'short'}).format(Math.floor((Timestamp - new Date()) / (60 * 1000)), 'day');
const Result = `<code style="color: orange;">${Months[Timestamp.getMonth()]} ${Timestamp.getDate()}, ${Timestamp.getFullYear()} (${['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][Timestamp.getDay() - 1]}) at ${Timestamp.getHours() - 12}:${String(Timestamp.getMinutes()).padStart(2, '0')} (${Distance})</code>`;
FormattedText = FormattedText.replaceAll(match[0], Result);
console.log(FormattedText);
}
text.innerHTML = FormattedText
text.innerHTML = FormattedText;
}
}

View file

@ -1,22 +1,22 @@
const StoreItems = document.getElementById('store-items')
const StoreItems = document.getElementById('store-items');
var Settings;
let Utilities;
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings
Settings = result.PolyPlus_Settings;
if (Settings.IRLPriceWithCurrency.Enabled === true) {
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
for (let item of Array.from(StoreItems.children)) {
IRLPrice(item)
IRLPrice(item);
}
const PreviousPage = document.querySelector('#store-prev a')
const NextPage = document.querySelector('#store-next a')
const PreviousPage = document.querySelector('#store-prev a');
const NextPage = document.querySelector('#store-next a');
//PreviousPage.addEventListener('click', IRLPrice)
//NextPage.addEventListener('click', IRLPrice)
})();
@ -24,24 +24,24 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
});
async function IRLPrice(item) {
const Price = item.getElementsByClassName('text-success')[0]
if (Price !== undefined && Price.innerText !== "Free") {
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
const Price = item.getElementsByClassName('text-success')[0];
if (Price !== undefined && Price.innerText !== 'Free') {
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency);
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.fontSize = '0.7rem';
Span.innerText = ' ($' + IRLResult.result + ' ' + IRLResult.display + ')';
Price.appendChild(Span);
}
}
const observer = new MutationObserver(async function (list) {
for (const record of list) {
for (const element of record.addedNodes) {
if (element.tagName === "DIV" && element.classList.value === 'col-auto mb-3') {
if (element.tagName === 'DIV' && element.classList.value === 'col-auto mb-3') {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice(element)
IRLPrice(element);
}
}
}

View file

@ -1,57 +1,56 @@
const AssetID = window.location.pathname.split('/')[2]
const LibraryType = document.querySelectorAll('ol a')[1].innerText
const LibraryTypes = [
"Models",
"Audio",
"Decal",
"Mesh"
]
const AssetID = window.location.pathname.split('/')[2];
const LibraryType = document.querySelectorAll('ol a')[1].innerText;
const LibraryTypes = ['Models', 'Audio', 'Decal', 'Mesh'];
if (LibraryTypes.indexOf(LibraryType) !== -1) {
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = result.PolyPlus_Settings || {};
if (Settings.LibraryDownloadsOn === false) { return }
if (Settings.LibraryDownloadsOn === false) {
return;
}
const Dropdown = document.querySelector('#app div[style] .dropdown-menu li')
const Dropdown = document.querySelector('#app div[style] .dropdown-menu li');
const DownloadLink = document.createElement('a')
DownloadLink.classList = 'dropdown-item text-warning'
DownloadLink.href = '#'
DownloadLink.innerHTML = `<i class="fa-duotone fa-download"></i> Download`
Dropdown.insertBefore(DownloadLink, Dropdown.children[Dropdown.children.length-1])
const DownloadLink = document.createElement('a');
DownloadLink.classList = 'dropdown-item text-warning';
DownloadLink.href = '#';
DownloadLink.innerHTML = `<i class="fa-duotone fa-download"></i> Download`;
Dropdown.insertBefore(DownloadLink, Dropdown.children[Dropdown.children.length - 1]);
switch (LibraryType) {
case 'Models':
DownloadLink.href = 'https://api.polytoria.com/v1/models/get-model?id=' + AssetID
break
DownloadLink.href = 'https://api.polytoria.com/v1/models/get-model?id=' + AssetID;
break;
case 'Audio':
const AudioBlob = new Blob([document.getElementsByTagName('audio')[0]], {type: 'octet-steam'})
DownloadLink.href = URL.createObjectURL(AudioBlob)
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.mp3'
const AudioBlob = new Blob([document.getElementsByTagName('audio')[0]], {type: 'octet-steam'});
DownloadLink.href = URL.createObjectURL(AudioBlob);
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.mp3';
case 'Decal':
const DecalBlob = new Blob([document.getElementsByClassName('store-thumbnail')[0]], {type: 'image/png'})
DownloadLink.href = URL.createObjectURL(DecalBlob)
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.png'
break
const DecalBlob = new Blob([document.getElementsByClassName('store-thumbnail')[0]], {type: 'image/png'});
DownloadLink.href = URL.createObjectURL(DecalBlob);
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.png';
break;
}
if (LibraryType === 'Mesh') {
let MeshURL = null
let MeshURL = null;
DownloadLink.addEventListener('click', async function () {
if (MeshURL !== null) { return }
MeshURL = await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + AssetID)
MeshURL = await MeshURL.json()
if (MeshURL !== null) {
return;
}
MeshURL = await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + AssetID);
MeshURL = await MeshURL.json();
if (MeshURL.success === true) {
DownloadLink.href = MeshURL.url
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.glb'
DownloadLink.href = MeshURL.url;
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.glb';
DownloadLink.click()
DownloadLink.click();
} else {
alert('Failure to fetch .glb file for mesh')
}
})
alert('Failure to fetch .glb file for mesh');
}
});
}
});
}

View file

@ -3,17 +3,19 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
ApplyMembershipThemeOn: false,
ApplyMembershipThemeTheme: 0
};
if (Settings.ApplyMembershipThemeOn !== true) {return}
if (Settings.ApplyMembershipThemeOn !== true) {
return;
}
MembershipTheme = Settings.ApplyMembershipThemeTheme === 0 ? 'plus': 'plusdx'
MembershipTheme = Settings.ApplyMembershipThemeTheme === 0 ? 'plus' : 'plusdx';
document.addEventListener('DOMContentLoaded', function () {
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
return
return;
}
if (document.getElementsByTagName('NAV')[0].classList.contains('navbar-plus') === true || document.getElementsByTagName('NAV')[0].classList.contains('navbar-plusdx') === true) {
return
return;
}
const Navbar = document.querySelector('.navbar.navbar-expand-lg.navbar-light.bg-navbar.nav-topbar');
@ -24,22 +26,22 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
if (MembershipTheme === 'plusdx') {
let SidebarLogo = document.querySelector('.nav-sidebar img');
SidebarLogo.setAttribute('src', 'https://c0.ptacdn.com/static/images/branding/icon-plusdx.bd9daa92.svg')
let SidebarLogoLabel = document.createElement('div')
SidebarLogoLabel.classList = 'nplusdx-banner'
SidebarLogo.setAttribute('src', 'https://c0.ptacdn.com/static/images/branding/icon-plusdx.bd9daa92.svg');
let SidebarLogoLabel = document.createElement('div');
SidebarLogoLabel.classList = 'nplusdx-banner';
SidebarLogoLabel.innerHTML = `
<i class="pi pi-plusdx" style="margin-right:-0.4em"></i>
`
SidebarLogo.parentElement.appendChild(SidebarLogoLabel)
`;
SidebarLogo.parentElement.appendChild(SidebarLogoLabel);
if (window.location.pathname === "/home") {
let HomeUsernameText = document.getElementsByClassName('home-title2')[0]
HomeUsernameText.children[0].classList.add('text-plusdx')
let Label = document.createElement('div')
Label.classList = 'hplusdx-banner rounded-2'
Label.setAttribute('style', 'margin-top: -8px; animation-delay: 0.09s;')
Label.innerText = 'Deluxe'
HomeUsernameText.appendChild(Label)
if (window.location.pathname === '/home') {
let HomeUsernameText = document.getElementsByClassName('home-title2')[0];
HomeUsernameText.children[0].classList.add('text-plusdx');
let Label = document.createElement('div');
Label.classList = 'hplusdx-banner rounded-2';
Label.setAttribute('style', 'margin-top: -8px; animation-delay: 0.09s;');
Label.innerText = 'Deluxe';
HomeUsernameText.appendChild(Label);
}
}
});

View file

@ -1,55 +1,57 @@
!(() => {
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;
if (Type === 'store') {
if (document.querySelector('h5 .text-reset[href^="/users/"]')) {
CreatorID = document.querySelector('h5 .text-reset[href^="/users/"]').getAttribute('href').split('/')[2]
CreatorID = document.querySelector('h5 .text-reset[href^="/users/"]').getAttribute('href').split('/')[2];
} else {
CreatorID = 1
CreatorID = 1;
}
} else if (Type === 'places') {
CreatorID = document.querySelector('.mcard .col .text-muted [href^="/users/"]').getAttribute('href').split('/')[2]
CreatorID = document.querySelector('.mcard .col .text-muted [href^="/users/"]').getAttribute('href').split('/')[2];
} else if (Type === 'feed') {
CreatorID = document.querySelector('p a[href^="/users/"].text-reset').getAttribute('href').split('/')[2]
CreatorID = document.querySelector('p a[href^="/users/"].text-reset').getAttribute('href').split('/')[2];
} else if (Type === 'guilds') {
CreatorID = document.querySelector('[class^="userlink-"][href^="/users/"]').getAttribute('href').split('/')[2]
Comments = document.getElementById('wall-posts')
CreatorID = document.querySelector('[class^="userlink-"][href^="/users/"]').getAttribute('href').split('/')[2];
Comments = document.getElementById('wall-posts');
}
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)
LoadCreatorTag(element);
}
}
}
});
Observer.observe(Comments, {attributes: false, childList: true, subtree: false})
Observer.observe(Comments, {attributes: false, childList: true, subtree: false});
const LoadCreatorTag = function (element) {
let NameElement = element.querySelector('.text-reset[href^="/users/"]')
let NameElement = element.querySelector('.text-reset[href^="/users/"]');
if (Type === 'guilds') {
NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]')
NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]');
}
let UserID = NameElement.getAttribute('href').split('/')[2]
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)
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!"})
}
}
};
Array.from(Comments.children).forEach(element => {
LoadCreatorTag(element)
Array.from(Comments.children).forEach((element) => {
LoadCreatorTag(element);
});
})();

View file

@ -1,68 +1,68 @@
const PlaceID = window.location.pathname.split('/')[3]
const Form = document.querySelector('form[action="/create/place/update"]')
const PlaceID = window.location.pathname.split('/')[3];
const Form = document.querySelector('form[action="/create/place/update"]');
var Settings;
var PlaceData = null
var PlaceData = null;
!(async () => {
ActivityToggle()
ActivityToggle();
//RequestGameProfile()
CopyOwnedPlace()
})()
CopyOwnedPlace();
})();
async function ActivityToggle() {
if (PlaceData === null) {
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID)
PlaceData = await PlaceData.json()
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID);
PlaceData = await PlaceData.json();
}
let Status = PlaceData.isActive
let Status = PlaceData.isActive;
const DIV = document.createElement('div')
DIV.classList = 'form-group mt-4'
const DIV = document.createElement('div');
DIV.classList = 'form-group mt-4';
DIV.innerHTML = `
<label class="mb-2">
<h5 class="mb-0">Toggle Activity</h5>
<small class="text-muted">Make your place active or inactive (currently ${(Status === true) ? 'active' : 'inactive'}).</small>
<small class="text-muted">Make your place active or inactive (currently ${Status === true ? 'active' : 'inactive'}).</small>
</label>
<br>
`
`;
Form.insertBefore(DIV, Form.children[Form.children.length-1])
Form.insertBefore(DIV, Form.children[Form.children.length - 1]);
const ActivityBtn = document.createElement('button')
ActivityBtn.type = 'button'
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success')
ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'
DIV.appendChild(ActivityBtn)
const ActivityBtn = document.createElement('button');
ActivityBtn.type = 'button';
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success');
ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate';
DIV.appendChild(ActivityBtn);
ActivityBtn.addEventListener('click', function () {
fetch(`https://polytoria.com/api/places/${PlaceID}/toggle-active`, {
method: "POST",
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
}
})
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok ' + response.status)
throw new Error('Network not ok ' + response.status);
}
return response.json()
return response.json();
})
.then(data => {
Status = data.isActive
ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success')
.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)
.catch((error) => {
console.log(error);
});
});
}
function RequestGameProfile() {
const Div = document.createElement('div')
Div.classList = 'card mt-4'
const Div = document.createElement('div');
Div.classList = 'card mt-4';
Div.innerHTML = `
<div class="card-body">
<input type="text" class="form-control bg-dark mb-2" placeholder="Game Title..">
@ -73,13 +73,13 @@ function RequestGameProfile() {
<input type="color" class="form-control bg-dark mb-2" placeholder="Text Color..">
<button type="button" class="btn btn-primary">Submit Request</button>
</div>
`
Form.insertBefore(Div, Form.children[Form.children.length-1])
`;
Form.insertBefore(Div, Form.children[Form.children.length - 1]);
const SubmitBtn = Div.getElementsByTagName('button')[0]
const SubmitBtn = Div.getElementsByTagName('button')[0];
SubmitBtn.addEventListener('click', function () {
const CardBody = Div.children[0]
const CardBody = Div.children[0];
const Result = {
gameTitle: CardBody.children[0].value,
bg: CardBody.children[1].value,
@ -87,25 +87,25 @@ function RequestGameProfile() {
secondary: CardBody.children[3].value,
cardBg: CardBody.children[4].value,
text: CardBody.children[5].value
}
window.location.href = 'https://polyplus.vercel.app/app/game-profile.html?gameId=' + PlaceID + '&profile=' + encodeURIComponent(btoa(JSON.stringify(Result)))
};
window.location.href = 'https://polyplus.vercel.app/app/game-profile.html?gameId=' + PlaceID + '&profile=' + encodeURIComponent(btoa(JSON.stringify(Result)));
});
}
async function CopyOwnedPlace() {
console.log('ran function')
console.log('ran function');
if (PlaceData === null) {
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + 2640)
PlaceData = await PlaceData.json()
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + 2640);
PlaceData = await PlaceData.json();
}
if (PlaceData.creator.id !== parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).ID)) {
console.log('returned')
console.log('returned');
//return
}
const DIV = document.createElement('div')
DIV.classList = 'form-group mt-4'
const DIV = document.createElement('div');
DIV.classList = 'form-group mt-4';
DIV.innerHTML = `
<label class="mb-2">
<h5 class="mb-0">Download <code style="color: orange;">.poly</code> File</h5>
@ -113,46 +113,48 @@ async function CopyOwnedPlace() {
</label>
<br>
<button type="button" class="btn btn-primary">Download</button>
`
`;
Form.insertBefore(DIV, Form.children[Form.children.length-1])
Form.insertBefore(DIV, Form.children[Form.children.length - 1]);
const DownloadButton = DIV.getElementsByTagName('button')[0]
const DownloadButton = DIV.getElementsByTagName('button')[0];
DownloadButton.addEventListener('click', async function () {
console.log('clicked download epic')
console.log('clicked download epic');
let CreatorToken = await fetch('https://polytoria.com/api/places/edit', {
method: "POST",
method: 'POST',
headers: {
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
},
body: JSON.stringify({placeID: PlaceID})
})
CreatorToken = await CreatorToken.json()
CreatorToken = CreatorToken.token
});
CreatorToken = await CreatorToken.json();
CreatorToken = CreatorToken.token;
fetch(`https://api.polytoria.com/v1/places/get-place?id=${PlaceID}&tokenType=creator`, {
headers: {
'Authorization': CreatorToken
Authorization: CreatorToken
}
})
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.blob()
return response.blob();
})
.then(data => {
.then((data) => {
//const JSONBlob = new Blob([data], {type: "application/xml"})
const DownloadURL = URL.createObjectURL(data)
const DownloadURL = URL.createObjectURL(data);
const Link = document.createElement('a')
Link.href = DownloadURL
Link.download = PlaceData.name + '.poly'
document.body.appendChild(Link)
Link.click()
Link.remove()
})
.catch(error => {console.log(error)});
const Link = document.createElement('a');
Link.href = DownloadURL;
Link.download = PlaceData.name + '.poly';
document.body.appendChild(Link);
Link.click();
Link.remove();
})
.catch((error) => {
console.log(error);
});
});
}

View file

@ -3,19 +3,19 @@
*/
!(() => {
return
const PlaceID = parseInt(window.location.pathname.split('/')[2])
return;
const PlaceID = parseInt(window.location.pathname.split('/')[2]);
fetch('https://polytoria.com/home')
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.text()
return response.text();
})
.then(data => {
const Parser = new DOMParser()
const Doc = Parser.parseFromString(data, 'text/html')
.then((data) => {
const Parser = new DOMParser();
const Doc = Parser.parseFromString(data, 'text/html');
fetch('https://polytoria.com/api/places/join', {
method: 'POST',
@ -24,22 +24,26 @@
'X-Csrf-Token': Doc.querySelector('[name="_csrf"]').value
},
body: JSON.stringify({
'placeID': PlaceID
placeID: PlaceID
})
})
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
if (data.success !== true) {throw new Error(data.message)}
.then((data) => {
if (data.success !== true) {
throw new Error(data.message);
}
setTimeout(function () {
window.location.href = 'polytoria://client/' + data.token
window.location.href = 'https://polytoria.com/places/' + PlaceID
}, 5000)
})
.catch(error => {console.log(error)})
window.location.href = 'polytoria://client/' + data.token;
window.location.href = 'https://polytoria.com/places/' + PlaceID;
}, 5000);
})
.catch((error) => {
console.log(error);
});
});
})();

View file

@ -1,110 +1,112 @@
const PlaceID = window.location.pathname.split('/')[2]
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID
const GameCreator = document.querySelector('#main-content .card-body .col div.text-muted a[href^="/users/"]').getAttribute('href').split('/')[2]
const PlaceID = window.location.pathname.split('/')[2];
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID;
const GameCreator = document.querySelector('#main-content .card-body .col div.text-muted a[href^="/users/"]').getAttribute('href').split('/')[2];
let Utilities;
var Settings;
var PinnedGamesData = []
var PinnedGamesData = [];
let GamePinned;
let InfoColumns = document.querySelectorAll('#main-content .col:has(#likes-data-container) .card:has(.fas.fa-chart-bar) 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')
const GamepassesTab = document.getElementById('gamepasses-tabpane')
const Achievements = Array.from(AchievementsTab.getElementsByClassName('card')) || []
const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || []
const AchievementsTab = document.getElementById('achievements-tabpane');
const GamepassesTab = document.getElementById('gamepasses-tabpane');
const Achievements = Array.from(AchievementsTab.getElementsByClassName('card')) || [];
const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [];
!(() => {
if (PlaceID === undefined) { return }
if (PlaceID === undefined) {
return;
}
const DataContainer = document.getElementById('likes-data-container')
const DataContainer = document.getElementById('likes-data-container');
const RatingsData = {
Likes: parseInt(DataContainer.getAttribute('data-like-count')),
Dislikes: parseInt(DataContainer.getAttribute('data-dislike-count')),
Percentage: null
}
RatingsData.Percentage = Math.floor((RatingsData.Likes / (RatingsData.Likes + RatingsData.Dislikes)) * 100)
const RatingsContainer = document.getElementById('thumbup-btn').parentElement.parentElement
};
RatingsData.Percentage = Math.floor((RatingsData.Likes / (RatingsData.Likes + RatingsData.Dislikes)) * 100);
const RatingsContainer = document.getElementById('thumbup-btn').parentElement.parentElement;
const PercentageLabel = document.createElement('small')
PercentageLabel.classList = 'text-muted'
PercentageLabel.style.fontSize = '0.8rem'
PercentageLabel.style.marginLeft = '10px'
PercentageLabel.style.marginRight = '10px'
const PercentageLabel = document.createElement('small');
PercentageLabel.classList = 'text-muted';
PercentageLabel.style.fontSize = '0.8rem';
PercentageLabel.style.marginLeft = '10px';
PercentageLabel.style.marginRight = '10px';
if (!isNaN(RatingsData.Percentage)) {
PercentageLabel.innerText = RatingsData.Percentage + '%'
PercentageLabel.innerText = RatingsData.Percentage + '%';
} else {
PercentageLabel.innerText = 'N/A'
PercentageLabel.innerText = 'N/A';
}
RatingsContainer.children[0].appendChild(PercentageLabel)
RatingsContainer.children[0].appendChild(PercentageLabel);
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
Settings = result.PolyPlus_Settings || {}
Settings = result.PolyPlus_Settings || {};
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
if (Settings.PinnedGamesOn === true) {
PinnedGames()
PinnedGames();
}
if (Settings.InlineEditingOn === true && GameCreator === UserID) {
InlineEditing()
InlineEditing();
}
const Description = document.querySelector('.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small')
const Description = document.querySelector('.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small');
if (Settings.GameProfilesOn === true && Description !== null) {
const GameProfileRegex = /p\+gp;(#(?:[A-Fa-f0-9]{3}){1,2}\b(;#(?:[A-Fa-f0-9]{3}){1,2}\b)+)/gm
const GameProfileRegex = /p\+gp;(#(?:[A-Fa-f0-9]{3}){1,2}\b(;#(?:[A-Fa-f0-9]{3}){1,2}\b)+)/gm;
if (GameProfileRegex.test(Description.innerText)) {
const Info = GameProfileRegex.exec(Description.innerText)[1].split(';')
GameProfile(Info)
const Info = GameProfileRegex.exec(Description.innerText)[1].split(';');
GameProfile(Info);
}
}
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
IRLPrice();
}
if (Settings.ShowPlaceRevenueOn === true) {
const NameRow = document.createElement('li')
NameRow.innerText = 'Revenue:'
const NameRow = document.createElement('li');
NameRow.innerText = 'Revenue:';
CalculateRevenueButton = document.createElement('li')
CalculateRevenueButton.classList = 'fw-normal text-success'
CalculateRevenueButton.style.letterSpacing = '0px'
CalculateRevenueButton = document.createElement('li');
CalculateRevenueButton.classList = 'fw-normal text-success';
CalculateRevenueButton.style.letterSpacing = '0px';
CalculateRevenueButton.innerHTML = `
<a class="text-decoration-underline text-success" style="text-decoration-color: rgb(15, 132, 79) !important;">$ Calculate</a>
`
`;
InfoColumns[0].appendChild(NameRow)
InfoColumns[1].appendChild(CalculateRevenueButton)
InfoColumns[0].appendChild(NameRow);
InfoColumns[1].appendChild(CalculateRevenueButton);
let Calculating = false
let Calculating = false;
CalculateRevenueButton.addEventListener('click', function () {
if (Calculating === false) {
Calculating = true
CalculateRevenueButton.innerText = '$ Calculating...'
PlaceRevenue()
Calculating = true;
CalculateRevenueButton.innerText = '$ Calculating...';
PlaceRevenue();
}
})
});
}
if (AchievementsTab.getElementsByClassName('display-3')[0] === undefined) {
AchievementProgressBar()
AchievementEarnedPercentage()
AchievementProgressBar();
AchievementEarnedPercentage();
for (let achievement of Achievements) {
if ((achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined) === false) {
achievement.style.opacity = '0.5'
achievement.style.opacity = '0.5';
}
}
}
});
})()
})();
async function PinnedGames() {
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
@ -112,21 +114,21 @@ async function PinnedGames() {
const PinBtn = document.createElement('button');
PinBtn.classList = 'btn btn-warning btn-sm';
PinBtn.style = 'position: absolute; right: 0; margin-right: 7px;'
PinBtn.style = 'position: absolute; right: 0; margin-right: 7px;';
if (PinnedGamesData.includes(parseInt(PlaceID))) {
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
} else {
if (PinnedGamesData.length !== Utilities.Limits.PinnedGames) {
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
} else {
PinBtn.setAttribute('disabled', true)
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`
PinBtn.setAttribute('disabled', true);
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`;
}
}
PinBtn.addEventListener('click', function () {
PinBtn.setAttribute('disabled', 'true')
PinBtn.setAttribute('disabled', 'true');
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
PinnedGamesData = result.PolyPlus_PinnedGames || [];
@ -145,17 +147,17 @@ async function PinnedGames() {
const Index = PinnedGamesData.indexOf(parseInt(PlaceID));
if (Index !== -1) {
PinnedGamesData.splice(Index, 1);
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
} else {
PinnedGamesData.push(parseInt(PlaceID));
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
}
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': PinnedGamesData, arrayOrder: true }, function() {
chrome.storage.sync.set({PolyPlus_PinnedGames: PinnedGamesData, arrayOrder: true}, function () {
setTimeout(function () {
PinBtn.removeAttribute('disabled')
console.log(PinnedGamesData)
}, 1250)
PinBtn.removeAttribute('disabled');
console.log(PinnedGamesData);
}, 1250);
});
});
});
@ -181,14 +183,14 @@ async function PinnedGames() {
}
*/
if (PinnedGamesData.includes(parseInt(PlaceID))) {
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
} else {
if (PinnedGamesData.length !== Utilities.Limits.PinnedGames) {
PinBtn.removeAttribute('disabled')
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
PinBtn.removeAttribute('disabled');
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
} else {
PinBtn.setAttribute('disabled', true)
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`
PinBtn.setAttribute('disabled', true);
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`;
}
}
});
@ -204,136 +206,134 @@ async function InlineEditing() {
- Make it possible to edit the place's genre
*/
let Editing = false
let Editing = false;
const Style = document.createElement('style')
const Style = document.createElement('style');
Style.innerHTML = `
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-visible {display: block !important;}
.polyplus-inlineEditing-visible {display: none;}
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-hidden {display: none !important;}
.polyplus-inlineEditing-hidden {display: block;}
`
document.body.prepend(Style)
`;
document.body.prepend(Style);
const Inputs = [
{
name: "name",
name: 'name',
element: null,
reference: '.card-header h1[style="font-weight:800;font-size:1.6em"]',
placeholder: "Place Title..",
placeholder: 'Place Title..',
required: true,
isTextarea: false,
styles: 'font-weight:800;font-size:1.6em'
},
{
name: "description",
name: 'description',
element: null,
reference: '.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small',
placeholder: "Place Description..",
placeholder: 'Place Description..',
required: false,
isTextarea: true,
styles: 'height:300px; overflow-y:auto;'
}
]
console.log(Inputs)
];
console.log(Inputs);
for (let input of Inputs) {
let Input = (input.isTextarea === true) ? document.createElement('textarea') : document.createElement('input')
input.element = Input
let Input = input.isTextarea === true ? document.createElement('textarea') : document.createElement('input');
input.element = Input;
const Reference = document.querySelector(input.reference)
const Reference = document.querySelector(input.reference);
Input.classList = 'polyplus-inlineEditing-visible form-control'
Input.placeholder = input.placeholder
Input.value = Reference.innerText
Input.style = input.styles
Input.classList = 'polyplus-inlineEditing-visible form-control';
Input.placeholder = input.placeholder;
Input.value = Reference.innerText;
Input.style = input.styles;
Reference.classList.add('polyplus-inlineEditing-hidden')
Reference.parentElement.appendChild(Input)
Reference.classList.add('polyplus-inlineEditing-hidden');
Reference.parentElement.appendChild(Input);
}
const PlaceGenre = document.getElementsByClassName('list-unstyled m-0 col')[0].children[3]
const PlaceGenre = document.getElementsByClassName('list-unstyled m-0 col')[0].children[3];
const Genres = [
"other",
"adventure",
"building",
"competitive",
"creative",
"fighting",
"funny",
"hangout",
"medieval",
"parkour",
"puzzle",
"racing",
"roleplay",
"sandbox",
"showcase",
"simulator",
"sports",
"strategy",
"survival",
"techdemo",
"trading",
"tycoon",
"western"
]
'other',
'adventure',
'building',
'competitive',
'creative',
'fighting',
'funny',
'hangout',
'medieval',
'parkour',
'puzzle',
'racing',
'roleplay',
'sandbox',
'showcase',
'simulator',
'sports',
'strategy',
'survival',
'techdemo',
'trading',
'tycoon',
'western'
];
const EditBtn = document.createElement('button');
EditBtn.classList = 'btn btn-primary btn-sm';
EditBtn.style = 'position: absolute; right: 0; margin-right: 7px;'
EditBtn.innerHTML = '<i class="fa-duotone fa-hammer"></i> <span>Edit Details</span>'
EditBtn.style = 'position: absolute; right: 0; margin-right: 7px;';
EditBtn.innerHTML = '<i class="fa-duotone fa-hammer"></i> <span>Edit Details</span>';
document.getElementsByClassName('card-header')[3].appendChild(EditBtn);
EditBtn.addEventListener('click', function () {
Editing = !Editing
Editing = !Editing;
EditBtn.children[0].classList.toggle('fa-hammer')
EditBtn.children[0].classList.toggle('fa-check-double')
EditBtn.children[0].classList.toggle('fa-fade')
EditBtn.children[0].classList.toggle('fa-hammer');
EditBtn.children[0].classList.toggle('fa-check-double');
EditBtn.children[0].classList.toggle('fa-fade');
document.body.setAttribute('data-polyplus-inlineEditing', Editing)
document.body.setAttribute('data-polyplus-inlineEditing', Editing);
if (Editing === false) {
const Send = new FormData()
Send.append("_csrf", document.querySelector('input[name="_csrf"]').value)
Send.append("id", PlaceID)
const Send = new FormData();
Send.append('_csrf', document.querySelector('input[name="_csrf"]').value);
Send.append('id', PlaceID);
for (let input of Inputs) {
console.log('start of loop')
Send.append(input.name, input.element.value)
console.log('start of loop');
Send.append(input.name, input.element.value);
}
console.log('after')
fetch('/create/place/update', {method:"POST",body:Send})
.then(response => {
console.log('after');
fetch('/create/place/update', {method: 'POST', body: Send})
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.text()
return response.text();
})
.then(data => {
console.log('Successfully edited game')
.then((data) => {
console.log('Successfully edited game');
for (let input of Inputs) {
const Reference = document.querySelector(input.reference)
Reference.innerText = input.element.value
const Reference = document.querySelector(input.reference);
Reference.innerText = input.element.value;
}
})
.catch(error => {
alert('Error while saving changes')
console.log('Error while editing game')
.catch((error) => {
alert('Error while saving changes');
console.log('Error while editing game');
});
}
});
}
async function GameProfile(data) {
document.querySelector('h1.my-0')
.setAttribute('game-key', 'true');
document.querySelector('div[style="min-height: 60vh;"]')
.id = 'gameprofile';
document.querySelector('h1.my-0').setAttribute('game-key', 'true');
document.querySelector('div[style="min-height: 60vh;"]').id = 'gameprofile';
const Style = document.createElement('style')
const Style = document.createElement('style');
Style.innerHTML = `
div#app {
@ -362,55 +362,55 @@ async function GameProfile(data) {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
`
document.body.appendChild(Style)
`;
document.body.appendChild(Style);
}
async function IRLPrice() {
const Gamepasses = document.querySelector('#gamepasses-tabpane .row.flex-row').children
const Gamepasses = document.querySelector('#gamepasses-tabpane .row.flex-row').children;
for (let gamepass of Gamepasses) {
const Price = gamepass.getElementsByClassName('text-success')[0]
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
const Price = gamepass.getElementsByClassName('text-success')[0];
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency);
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.fontSize = '0.7rem';
Span.innerText = '($' + IRLResult.result + ' ' + IRLResult.display + ')';
Price.appendChild(Span);
}
}
async function PlaceRevenue() {
const BricksPerView = 5
const BricksPerView = 5;
let PlaceDetails = await fetch('https://api.polytoria.com/v1/places/' + PlaceID)
PlaceDetails = await PlaceDetails.json()
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 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 Total = round5(PlaceDetails.uniqueVisits) / 5;
let Revenue = round5(PlaceDetails.uniqueVisits) / 5;
let CreatorTax = 0.35
let CreatorTax = 0.35;
switch (CreatorDetails.membershipType) {
case 'plus':
CreatorTax = 0.25
break
CreatorTax = 0.25;
break;
case 'plusDeluxe':
CreatorTax = 0.15
break
CreatorTax = 0.15;
break;
}
let Achievements = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/achievements')
Achievements = await Achievements.json()
let Achievements = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/achievements');
Achievements = await Achievements.json();
let Gamepasses = await fetch('https://api.polytoria.com/v1/places/' + PlaceID + '/gamepasses')
Gamepasses = await Gamepasses.json()
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)
const PriceAfterTax = Math.floor(gamepass.asset.price - gamepass.asset.price * CreatorTax);
Revenue += PriceAfterTax * gamepass.asset.sales;
}
/*
@ -423,84 +423,93 @@ async function PlaceRevenue() {
}
*/
const ResultText = document.createElement('li')
ResultText.classList = 'fw-normal text-success'
ResultText.style.letterSpacing = '0px'
ResultText.innerHTML = `<i class="pi pi-brick mx-1"></i> ~` + Revenue.toLocaleString()
const ResultText = document.createElement('li');
ResultText.classList = 'fw-normal text-success';
ResultText.style.letterSpacing = '0px';
ResultText.innerHTML = `<i class="pi pi-brick mx-1"></i> ~` + Revenue.toLocaleString();
CalculateRevenueButton.remove()
InfoColumns[1].appendChild(ResultText)
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); } }
function round5(number) {
const remainder = number % 5;
if (remainder < 2.5) {
return number - remainder;
} else {
return number + (5 - remainder);
}
}
function AchievementProgressBar() {
const AchievementCount = Achievements.length
let AchievementsEarned = 0
const AchievementCount = Achievements.length;
let AchievementsEarned = 0;
for (let achievement of Achievements) {
Achieved = (achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined)
Achieved = achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined;
if (Achieved === true) {
AchievementsEarned++
AchievementsEarned++;
}
}
const PercentageEarned = ((AchievementsEarned*100)/AchievementCount).toFixed(0)
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 = `<div class="progress-bar progress-bar-striped text-bg-warning" style="width: ${PercentageEarned}%">${PercentageEarned}%</div>`
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 = `<div class="progress-bar progress-bar-striped text-bg-warning" style="width: ${PercentageEarned}%">${PercentageEarned}%</div>`;
AchievementsTab.prepend(document.createElement('hr'))
AchievementsTab.prepend(ProgressBar)
AchievementsTab.prepend(document.createElement('hr'));
AchievementsTab.prepend(ProgressBar);
}
function AchievementEarnedPercentage() {
fetch('https://api.polytoria.com/v1/places/' + PlaceID)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
const UserCount = data.uniqueVisits
.then((data) => {
const UserCount = data.uniqueVisits;
for (let achievement of Achievements) {
const OwnerText = achievement.getElementsByClassName('text-muted small my-0')[0]
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)
const OwnerCount = parseInt(OwnerText.innerText.replace(/[^0-9]/g, ''));
const PercentageOfPlayers = ((OwnerCount * 100) / UserCount).toFixed(2);
OwnerText.innerHTML += " (" + PercentageOfPlayers + "%, " + GetAchievementDifficulty(PercentageOfPlayers) + ")"
OwnerText.innerHTML += ' (' + PercentageOfPlayers + '%, ' + GetAchievementDifficulty(PercentageOfPlayers) + ')';
}
})
.catch(error => {console.log(error)});
.catch((error) => {
console.log(error);
});
}
function GetAchievementDifficulty(percent) {
if (percent >= 90 && percent <= 100) {
return 'Freebie'
return 'Freebie';
} else if (percent >= 80 && percent <= 89.9) {
return 'Cake Walk'
return 'Cake Walk';
} else if (percent >= 50 && percent <= 79.9) {
return 'Easy'
return 'Easy';
} else if (percent >= 30 && percent <= 49.9) {
return 'Moderate'
return 'Moderate';
} else if (percent >= 20 && percent <= 29.9) {
return 'Challenging'
return 'Challenging';
} else if (percent >= 10 && percent <= 19.9) {
return 'Hard'
return 'Hard';
} else if (percent >= 5 && percent <= 9.9) {
return 'Extreme'
return 'Extreme';
} else if (percent >= 1 && percent <= 4.9) {
return 'Insane'
return 'Insane';
} else if (percent >= 0 && percent <= 0.9) {
return 'Impossible'
return 'Impossible';
}
}

View file

@ -7,24 +7,27 @@ let Settings;
let PinnedGamesData;
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames'], function (result) {
Settings = result.PolyPlus_Settings || {}
PinnedGamesData = result.PolyPlus_PinnedGames || []
Settings = result.PolyPlus_Settings || {};
PinnedGamesData = result.PolyPlus_PinnedGames || [];
if (Settings.PinnedGamesOn === true) {}
})
if (Settings.PinnedGamesOn === true) {
}
});
function PinnedGames() {
for (let game of PinnedGamesData) {
fetch('https://api.polytoria.com/v1/places/' + game)
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
.then((data) => {
// epic
})
.catch(error => {console.log(error)})
.catch((error) => {
console.log(error);
});
}
}

View file

@ -1,18 +1,18 @@
const SettingsURL = chrome.runtime.getURL('settings.html')
const InExtensionSettings = (window.location.pathname.split('/')[3] === "polyplus" && window.location.hash !== "#dev")
const SettingsURL = chrome.runtime.getURL('settings.html');
const InExtensionSettings = window.location.pathname.split('/')[3] === 'polyplus' && window.location.hash !== '#dev';
if (InExtensionSettings === true) {
window.location.href = SettingsURL + window.location.hash
window.location.href = SettingsURL + window.location.hash;
}
document.addEventListener('DOMContentLoaded', function () {
const Nav = document.getElementsByClassName('nav nav-pills')[0]
const Nav = document.getElementsByClassName('nav nav-pills')[0];
const PolyPlusItem = document.createElement('a')
PolyPlusItem.classList = 'nav-link'
PolyPlusItem.href = SettingsURL
const PolyPlusItem = document.createElement('a');
PolyPlusItem.classList = 'nav-link';
PolyPlusItem.href = SettingsURL;
PolyPlusItem.innerHTML = `
<i class="fa-regular fa-sparkles me-1"></i> <span class="pilltitle">Poly+</span>
`
`;
Nav.insertBefore(PolyPlusItem, Nav.getElementsByTagName('hr')[0])
Nav.insertBefore(PolyPlusItem, Nav.getElementsByTagName('hr')[0]);
});

View file

@ -1,6 +1,6 @@
const ItemID = window.location.pathname.split('/')[2]
const ItemType = document.querySelector('.row .badge').innerHTML
console.log(ItemType)
const ItemID = window.location.pathname.split('/')[2];
const ItemType = document.querySelector('.row .badge').innerHTML;
console.log(ItemType);
var Settings;
var ItemWishlist;
@ -14,54 +14,54 @@ var Utilities;
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
Settings = result.PolyPlus_Settings || {}
Settings = result.PolyPlus_Settings || {};
PurchaseBtn = document.querySelector('.btn[onclick^="buy"]')
PurchaseBtn = document.querySelector('.btn[onclick^="buy"]');
if (PurchaseBtn === null) {
PurchaseBtn = document.querySelector('.btn#purchase-button')
PurchaseBtn = document.querySelector('.btn#purchase-button');
}
ItemOwned = (PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null)
ItemOwned = PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null;
if (PurchaseBtn.getAttribute('data-seller-name')) {
PurchaseBtn.setAttribute('data-bs-toggle', 'tooltip')
PurchaseBtn.setAttribute('data-bs-title', 'Sold by ' + PurchaseBtn.getAttribute('data-seller-name'))
Utilities.InjectResource('registerTooltips')
PurchaseBtn.setAttribute('data-bs-toggle', 'tooltip');
PurchaseBtn.setAttribute('data-bs-title', 'Sold by ' + PurchaseBtn.getAttribute('data-seller-name'));
Utilities.InjectResource('registerTooltips');
}
if (Settings.IRLPriceWithCurrency.Enabled === true && ItemOwned === false) {
IRLPrice()
IRLPrice();
}
if (Settings.ItemWishlistOn === true) {
HandleItemWishlist()
HandleItemWishlist();
}
if (Settings.TryOnItemsOn === true && (Utilities.MeshTypes.indexOf(ItemType.toLowerCase()) !== -1 || Utilities.TextureTypes.indexOf(ItemType.toLowerCase()) !== -1)) {
TryOnItems()
TryOnItems();
}
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)')[2];
if (Sales.children[1].innerText === '0') {
InitialOwners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json())
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].innerText = 'Owners';
Sales.children[1].innerText = Owners.total.toLocaleString();
}
}
if (document.getElementById('resellers') !== null) {
if (Settings.HoardersList.Enabled === true) {
console.log(parseInt(Settings.HoardersList.MinCopies))
HoardersList(parseInt(Settings.HoardersList.MinCopies), Settings.HoardersList.AvatarsEnabled)
console.log(parseInt(Settings.HoardersList.MinCopies));
HoardersList(parseInt(Settings.HoardersList.MinCopies), Settings.HoardersList.AvatarsEnabled);
}
} else if (document.getElementById('timer') && /\d/.test(document.getElementById('timer').innerText)) {
CheckOwner()
CheckOwner();
}
})
});
})();
chrome.storage.onChanged.addListener(function (changes, namespace) {
@ -70,23 +70,23 @@ chrome.storage.onChanged.addListener(function(changes, namespace) {
ItemWishlist = result.PolyPlus_ItemWishlist || [];
if (Array.isArray(ItemWishlist) && ItemWishlist.includes(parseInt(ItemID))) {
WishlistBtn.classList = 'btn btn-danger btn-sm'
WishlistBtn.classList = 'btn btn-danger btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Un-Wishlist Item
`
`;
} else {
if (!(ItemWishlist.length === 25)) {
WishlistBtn.removeAttribute('disabled')
WishlistBtn.classList = 'btn btn-warning btn-sm'
WishlistBtn.removeAttribute('disabled');
WishlistBtn.classList = 'btn btn-warning btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Wishlist Item
`
`;
} else {
WishlistBtn.setAttribute('disabled', true)
WishlistBtn.classList = 'btn btn-warning btn-sm'
WishlistBtn.setAttribute('disabled', true);
WishlistBtn.classList = 'btn btn-warning btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Wishlist Item
`
`;
}
}
});
@ -94,210 +94,212 @@ 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'
Span.style.fontWeight = 'normal'
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency)
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
PurchaseBtn.appendChild(Span)
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';
Span.style.fontWeight = 'normal';
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency);
Span.innerText = '($' + IRLResult.result + ' ' + IRLResult.display + ')';
PurchaseBtn.appendChild(Span);
}
function HandleItemWishlist() {
const DescriptionText = document.querySelector('.mcard .card-body:has(p)')
WishlistBtn = document.createElement('button')
const DescriptionText = document.querySelector('.mcard .card-body:has(p)');
WishlistBtn = document.createElement('button');
chrome.storage.sync.get(['PolyPlus_ItemWishlist'], function (result) {
ItemWishlist = result.PolyPlus_ItemWishlist || [];
if (ItemOwned === true) {
if (ItemWishlist.includes(parseInt(ItemID))) {
ItemWishlist.splice(ItemWishlist.indexOf(parseInt(ItemID)), 1)
chrome.storage.sync.set({'PolyPlus_ItemWishlist': ItemWishlist, arrayOrder: true});
ItemWishlist.splice(ItemWishlist.indexOf(parseInt(ItemID)), 1);
chrome.storage.sync.set({PolyPlus_ItemWishlist: ItemWishlist, arrayOrder: true});
}
return
return;
}
if (ItemOwned === true) {
return
return;
} else if (ItemOwned === true && ItemWishlist.includes(parseInt(ItemID))) {
ItemWishlist.splice(ItemWishlist.indexOf(parseInt(ItemID)), 1)
return
ItemWishlist.splice(ItemWishlist.indexOf(parseInt(ItemID)), 1);
return;
}
if (ItemWishlist.includes(parseInt(ItemID))) {
WishlistBtn.classList = 'btn btn-danger btn-sm'
WishlistBtn.classList = 'btn btn-danger btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Un-Wishlist Item
`
`;
} else {
WishlistBtn.classList = 'btn btn-warning btn-sm'
WishlistBtn.classList = 'btn btn-warning btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Wishlist Item
`
`;
}
WishlistBtn.addEventListener('click', function () {
WishlistBtn.setAttribute('disabled', true)
WishlistBtn.setAttribute('disabled', true);
chrome.storage.sync.get(['PolyPlus_ItemWishlist'], function (result) {
ItemWishlist = result.PolyPlus_ItemWishlist || [];
let i = ItemWishlist.indexOf(parseInt(ItemID))
let i = ItemWishlist.indexOf(parseInt(ItemID));
if (i !== -1) {
ItemWishlist.splice(i, 1)
WishlistBtn.classList = 'btn btn-warning btn-sm'
ItemWishlist.splice(i, 1);
WishlistBtn.classList = 'btn btn-warning btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Wishlist Item
`
`;
} else {
ItemWishlist.push(parseInt(ItemID))
WishlistBtn.classList = 'btn btn-danger btn-sm'
ItemWishlist.push(parseInt(ItemID));
WishlistBtn.classList = 'btn btn-danger btn-sm';
WishlistBtn.innerHTML = `
<i class="fa fa-star" style="margin-right: 2.5px;"></i> Un-Wishlist Item
`
`;
}
chrome.storage.sync.set({'PolyPlus_ItemWishlist': ItemWishlist, arrayOrder: true}, function() {
chrome.storage.sync.set({PolyPlus_ItemWishlist: ItemWishlist, arrayOrder: true}, function () {
setTimeout(function () {
WishlistBtn.removeAttribute('disabled')
}, 1250)
WishlistBtn.removeAttribute('disabled');
}, 1250);
});
});
});
DescriptionText.appendChild(document.createElement('br'))
DescriptionText.appendChild(WishlistBtn)
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"
}
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
let AssetType = document.querySelector('.px-4.px-lg-0.text-muted.text-uppercase.mb-3 .badge').innerHTML;
const ItemThumbnail = document.getElementsByClassName('store-thumbnail')[0]
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 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-warning'
TryOnBtn.style = 'position: absolute; bottom: 60px; right: 10px;'
const TryOnBtn = document.createElement('button');
TryOnBtn.classList = 'btn btn-warning';
TryOnBtn.style = 'position: absolute; bottom: 60px; right: 10px;';
if (document.getElementsByClassName('3dviewtoggler')[0] === undefined) {
TryOnBtn.style.bottom = '15px'
TryOnBtn.style.bottom = '15px';
}
//TryOnBtn.setAttribute('data-bs-toggle', 'tooltip')
//TryOnBtn.setAttribute('data-bs-title', 'Try this item on your avatar')
TryOnBtn.innerHTML = '<i class="fa-duotone fa-vial"></i>'
TryOnBtn.innerHTML = '<i class="fa-duotone fa-vial"></i>';
TryOnBtn.addEventListener('click', function () {
fetch("https://api.polytoria.com/v1/users/" + JSON.parse(window.localStorage.getItem('p+account_info')).ID + "/avatar")
.then(response => {
fetch('https://api.polytoria.com/v1/users/' + JSON.parse(window.localStorage.getItem('p+account_info')).ID + '/avatar')
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
data.assets.forEach(item => {
.then((data) => {
data.assets.forEach((item) => {
switch (item.type) {
case 'hat':
Avatar.items[Avatar.items.length] = item.path || ''
break
Avatar.items[Avatar.items.length] = item.path || '';
break;
case 'face':
Avatar.face = item.path || ''
break
Avatar.face = item.path || '';
break;
case 'tool':
Avatar.tool = item.path || ''
break
Avatar.tool = item.path || '';
break;
case 'shirt':
Avatar.shirt = item.path || ''
break
Avatar.shirt = item.path || '';
break;
case 'pants':
Avatar.pants = item.path || ''
break
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
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 (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 => {
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 => {
.then((data) => {
if (ItemType === 'tool') {
Avatar.tool = data.url
Avatar.tool = data.url;
} else {
Avatar.items.push(data.url)
Avatar.items.push(data.url);
}
console.log(Avatar)
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
console.log(Avatar);
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)));
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
} 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 => {
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 => {
.then((data) => {
switch (AssetType) {
case 'Shirt':
console.log('IS SHIRT')
Avatar.shirt = data.url
break
console.log('IS SHIRT');
Avatar.shirt = data.url;
break;
case 'Pants':
console.log('IS PANTS')
Avatar.pants = data.url
break
console.log('IS PANTS');
Avatar.pants = data.url;
break;
case 'Face':
console.log('IS FACE')
Avatar.face = data.url
break
console.log('IS FACE');
Avatar.face = data.url;
break;
}
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)));
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
}
})
.catch(error => {
.catch((error) => {
console.error('Fetch error:', error);
});
TryOnModal.showModal()
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;')
let TryOnModal = document.createElement('dialog');
TryOnModal.classList = 'polyplus-modal';
TryOnModal.setAttribute('style', 'width: 450px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;');
TryOnModal.innerHTML = `
<div class="row text-muted mb-2" style="font-size: 0.8rem;">
<div class="col">
@ -309,118 +311,133 @@ function TryOnItems() {
</div>
</div>
<div class="modal-body"></div>
`
`;
document.body.prepend(TryOnModal)
ItemThumbnail.parentElement.appendChild(TryOnBtn)
TryOnModal.children[1].prepend(TryIFrame)
document.body.prepend(TryOnModal);
ItemThumbnail.parentElement.appendChild(TryOnBtn);
TryOnModal.children[1].prepend(TryIFrame);
//Utilities.InjectResource('registerTooltips')
}
async function HoardersList(min, avatars) {
let Page = 0
let Tabs = document.getElementById('store-tabs')
let Page = 0;
let Tabs = document.getElementById('store-tabs');
const Tab = document.createElement('li')
Tab.classList = 'nav-item'
const Tab = document.createElement('li');
Tab.classList = 'nav-item';
Tab.innerHTML = `
<a class="nav-link">
<i class="fas fa-calculator me-1"></i>
<span class="d-none d-sm-inline"><span class="pilltitle">Hoarders</span>
</a>
`
Tabs.appendChild(Tab)
`;
Tabs.appendChild(Tab);
const TabContent = document.createElement('div')
TabContent.classList = 'd-none'
const TabContent = document.createElement('div');
TabContent.classList = 'd-none';
TabContent.innerHTML = `
<small class="d-block text-center text-muted" style="font-size: 0.8rem;">
loading... (this may take a few seconds)
</small>
<lottie-player id="avatar-loading" src="https://c0.ptacdn.com/static/images/lottie/poly-brick-loading.2b51aa85.json" background="transparent" speed="1" style="width: 20%;height: auto;margin: -16px auto 50px;margin-top: 0px;" loop="" autoplay=""></lottie-player>
`
document.getElementById('owners').parentElement.appendChild(TabContent)
`;
document.getElementById('owners').parentElement.appendChild(TabContent);
// Add tab logic
Array.from(Tabs.children).forEach(tab => {
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')
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');
}
})
})
});
});
let Fetched = false
let Fetched = false;
Tab.addEventListener('click', async function () {
if (Fetched === true) { return }
Fetched = true
const Owners = []
if (InitialOwners === undefined) {
InitialOwners = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json())
if (Fetched === true) {
return;
}
Owners.push(...InitialOwners.inventories)
Fetched = true;
const Owners = [];
if (InitialOwners === undefined) {
InitialOwners = await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owners?limit=100')).json();
}
Owners.push(...InitialOwners.inventories);
// Get owners (up to 300, if needed)
if (InitialOwners.pages > 3) {
InitialOwners.pages = 3
InitialOwners.pages = 3;
}
if (InitialOwners.pages > 1 && OwnerPagesFetched < InitialOwners.pages) {
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 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 Formatted = {}
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)
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]
}
};
}
}
let Hoarders = await new Promise(async (resolve, reject) => {
const Sorted = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies)
const Sorted = Object.values(Formatted)
.filter((x, index) => x.copies >= min)
.sort((a, b) => b.copies - a.copies);
if (avatars === true) {
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;
}
}
resolve(Sorted)
})
let AmountOfHoarders = Hoarders.length
resolve(Sorted);
});
let AmountOfHoarders = Hoarders.length;
// Break hoarders into groups of 4
let Groups = []
let Groups = [];
while (Hoarders.length > 0) {
Groups.push(Hoarders.splice(0, 4))
Groups.push(Hoarders.splice(0, 4));
}
TabContent.innerHTML = `
<div id="p+hoarders-container">
${ (Groups[Page] !== undefined) ? Groups[Page].map((x) => `
${
Groups[Page] !== undefined
? Groups[Page].map(
(x) => `
<div class="card mb-3">
<div class="card-body">
<div class="row">
${ (avatars === true) ? `
${
avatars === true
? `
<div class="col-auto">
<img src="${x.user.avatar}" alt="${x.user.username}" width="72" class="rounded-circle border border-2 border-secondary bg-dark">
</div>
` : '' }
`
: ''
}
<div class="col d-flex align-items-center">
<div>
<h6 class="mb-1">
@ -443,7 +460,8 @@ async function HoardersList(min, avatars) {
</div>
</div>
</div>
`).join('')
`
).join('')
: `
<div class="card mb-3">
<div class="card-body text-center py-5 text-muted">
@ -452,7 +470,8 @@ async function HoardersList(min, avatars) {
<p class="mb-0">This item is fresh and doesn't have any hoarders yet! Come back later!</p>
</div>
</div>
`}
`
}
</div>
<nav aria-label="Hoarders">
<ul class="pagination justify-content-center">
@ -486,90 +505,97 @@ async function HoardersList(min, avatars) {
</li>
</ul>
</nav>
`
Utilities.InjectResource('registerTooltips')
`;
Utilities.InjectResource('registerTooltips');
const Container = document.getElementById('p+hoarders-container')
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 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')
MinCopies.selectedIndex = Array.from(MinCopies.children).indexOf(MinCopies.querySelector(`option[value="${min}"]`))
const MinCopies = document.getElementById('p+hoarders-min-copies');
MinCopies.selectedIndex = Array.from(MinCopies.children).indexOf(MinCopies.querySelector(`option[value="${min}"]`));
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
First.parentElement.classList.remove('disabled')
Prev.parentElement.classList.remove('disabled');
First.parentElement.classList.remove('disabled');
} else {
Prev.parentElement.classList.add('disabled')
First.parentElement.classList.add('disabled')
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')
Next.parentElement.classList.remove('disabled');
Last.parentElement.classList.remove('disabled');
} else {
Next.parentElement.classList.add('disabled')
Last.parentElement.classList.add('disabled')
Next.parentElement.classList.add('disabled');
Last.parentElement.classList.add('disabled');
}
First.addEventListener('click', function () {
if (Page > 0) {
Page = 0
UpdateHoardersList()
Page = 0;
UpdateHoardersList();
}
})
});
Prev.addEventListener('click', function () {
if (Page > 0) {
Page--
UpdateHoardersList()
Page--;
UpdateHoardersList();
}
})
});
Next.addEventListener('click', function () {
if (Page < Groups.length - 1) {
Page++
UpdateHoardersList()
Page++;
UpdateHoardersList();
}
})
});
Last.addEventListener('click', function () {
if (Page < Groups.length - 1) {
Page = Groups.length-1
UpdateHoardersList()
Page = Groups.length - 1;
UpdateHoardersList();
}
})
});
MinCopies.addEventListener('change', function () {
Page = 0
min = parseInt(MinCopies.options[MinCopies.selectedIndex].value)
Hoarders = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies)
AmountOfHoarders = Hoarders.length
Groups = []
Page = 0;
min = parseInt(MinCopies.options[MinCopies.selectedIndex].value);
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))
Groups.push(Hoarders.splice(0, 4));
}
UpdateHoardersList()
})
UpdateHoardersList();
});
const UpdateHoardersList = function () {
console.log(Hoarders, AmountOfHoarders, Groups)
Current.innerText = Page+1
console.log(Hoarders, AmountOfHoarders, Groups);
Current.innerText = Page + 1;
if (Groups[Page] !== undefined) {
Container.innerHTML = Groups[Page].map((x) => `
Container.innerHTML = Groups[Page].map(
(x) => `
<div class="card mb-3">
<div class="card-body">
<div class="row">
${ (avatars === true) ? `
${
avatars === true
? `
<div class="col-auto">
<img src="${x.user.avatar}" alt="${x.user.username}" width="72" class="rounded-circle border border-2 border-secondary bg-dark">
</div>
` : '' }
`
: ''
}
<div class="col d-flex align-items-center">
<div>
<h6 class="mb-1">
@ -587,9 +613,10 @@ async function HoardersList(min, avatars) {
</div>
</div>
</div>
`).join('')
`
).join('');
Utilities.InjectResource('registerTooltips')
Utilities.InjectResource('registerTooltips');
} else {
Container.innerHTML = `
<div class="card mb-3">
@ -599,34 +626,34 @@ async function HoardersList(min, avatars) {
<p class="mb-0">This item is fresh and doesn't have any hoarders yet! Come back later!</p>
</div>
</div>
`
`;
MinCopies.disabled = true
MinCopies.disabled = true;
}
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
First.parentElement.classList.remove('disabled')
Prev.parentElement.classList.remove('disabled');
First.parentElement.classList.remove('disabled');
} else {
Prev.parentElement.classList.add('disabled')
First.parentElement.classList.add('disabled')
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')
Next.parentElement.classList.remove('disabled');
Last.parentElement.classList.remove('disabled');
} else {
Next.parentElement.classList.add('disabled')
Last.parentElement.classList.add('disabled')
Next.parentElement.classList.add('disabled');
Last.parentElement.classList.add('disabled');
}
}
})
};
});
}
function CheckOwner() {
const ImageCard = document.querySelector('.card-body:has(.store-thumbnail)')
const ImageCard = document.querySelector('.card-body:has(.store-thumbnail)');
const CheckOwnerDiv = document.createElement('div')
CheckOwnerDiv.classList = 'mt-3 d-none'
const CheckOwnerDiv = document.createElement('div');
CheckOwnerDiv.classList = 'mt-3 d-none';
CheckOwnerDiv.innerHTML = `
<div class="input-group mb-2">
<input type="text" class="form-control bg-dark" placeholder="Username..">
@ -634,61 +661,61 @@ function CheckOwner() {
</div>
<b class="text-muted" style="font-size: 0.85rem;"><i class="fa-duotone fa-square-question mr-1"></i> ...</b>
`
`;
ImageCard.appendChild(CheckOwnerDiv)
ImageCard.appendChild(CheckOwnerDiv);
const ToggleButton = document.createElement('button')
ToggleButton.classList = 'btn btn-dark'
ToggleButton.style = 'position: absolute; bottom: 15px; left: 10px;'
const ToggleButton = document.createElement('button');
ToggleButton.classList = 'btn btn-dark';
ToggleButton.style = 'position: absolute; bottom: 15px; left: 10px;';
//ToggleButton.setAttribute('data-bs-toggle', 'tooltip')
//ToggleButton.setAttribute('data-bs-title', 'Quickly check if someone owns this item')
ToggleButton.innerHTML = '<i class="fa-duotone fa-bags-shopping"></i>'
ToggleButton.innerHTML = '<i class="fa-duotone fa-bags-shopping"></i>';
ImageCard.children[0].prepend(ToggleButton)
ImageCard.children[0].prepend(ToggleButton);
const UsernameInput = CheckOwnerDiv.getElementsByTagName('input')[0]
const CheckButton = CheckOwnerDiv.getElementsByTagName('button')[0]
const ResultText = CheckOwnerDiv.getElementsByTagName('b')[0]
const UsernameInput = CheckOwnerDiv.getElementsByTagName('input')[0];
const CheckButton = CheckOwnerDiv.getElementsByTagName('button')[0];
const ResultText = CheckOwnerDiv.getElementsByTagName('b')[0];
ToggleButton.addEventListener('click', function () {
if (CheckOwnerDiv.classList.contains('d-none')) {
ResultText.classList = ''
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...'
CheckOwnerDiv.classList.remove('d-none')
ResultText.classList = '';
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...';
CheckOwnerDiv.classList.remove('d-none');
} else {
CheckOwnerDiv.classList.add('d-none')
CheckOwnerDiv.classList.add('d-none');
}
})
});
UsernameInput.addEventListener('update', function () {
ResultText.classList = ''
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...'
})
ResultText.classList = '';
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...';
});
CheckButton.addEventListener('click', async function () {
const Username = UsernameInput.value
if (Username.trim() === "") {
ResultText.classList = ''
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...'
return
const Username = UsernameInput.value;
if (Username.trim() === '') {
ResultText.classList = '';
ResultText.innerHTML = '<i class="fa-duotone fa-square-question mr-1"></i> ...';
return;
}
const UserID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + Username)).json()).id
const UserID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + Username)).json()).id;
if (UserID !== undefined) {
const Owns = (await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owner?userID=' + UserID)).json())
const Owns = await (await fetch('https://api.polytoria.com/v1/store/' + ItemID + '/owner?userID=' + UserID)).json();
if (Owns.owned === true) {
ResultText.classList = 'text-success'
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' owns #' + Owns.inventory.serial + ' of ' + document.getElementsByTagName('h1')[0].innerText + '".'
ResultText.classList = 'text-success';
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' owns #' + Owns.inventory.serial + ' of ' + document.getElementsByTagName('h1')[0].innerText + '".';
} else {
ResultText.classList = 'text-danger'
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' does not own "' + document.getElementsByTagName('h1')[0].innerText + '".'
ResultText.classList = 'text-danger';
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' does not own "' + document.getElementsByTagName('h1')[0].innerText + '".';
}
} else {
ResultText.classList = 'text-warning'
ResultText.innerHTML = '<i class="fa-duotone fa-circle-exclamation mr-1"></i> No user found under the username "' + Username + '".'
ResultText.classList = 'text-warning';
ResultText.innerHTML = '<i class="fa-duotone fa-circle-exclamation mr-1"></i> No user found under the username "' + Username + '".';
}
})
});
}

View file

@ -1,65 +1,65 @@
const ItemID = window.location.pathname.split('/')[2]
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID
const ItemGrid = document.getElementById('assets')
const Categories = document.getElementById('store-categories').children[0]
const ItemID = window.location.pathname.split('/')[2];
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID;
const ItemGrid = document.getElementById('assets');
const Categories = document.getElementById('store-categories').children[0];
var Settings;
var Inventory = null;
var Utilities;
let EventItemsShown = false
let EventItemsShown = false;
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
Settings = result.PolyPlus_Settings || {};
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
if (Settings.IRLPriceWithCurrency.Enabled === true) {
Array.from(ItemGrid.children).forEach(element => {
LoadIRLPrices(element)
Array.from(ItemGrid.children).forEach((element) => {
LoadIRLPrices(element);
});
}
if (Settings.StoreOwnTagOn === true) {
Inventory = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=hat&limit=100')).json()).inventory
Inventory.concat(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=face&limit=100')).json()).inventory
Inventory.concat(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=tool&limit=100')).json()).inventory
console.log(Inventory)
Array.from(ItemGrid.children).forEach(element => {
LoadOwnedTags(element)
Inventory = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=hat&limit=100')).json()).inventory;
Inventory.concat(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=face&limit=100')).json()).inventory;
Inventory.concat(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=tool&limit=100')).json()).inventory;
console.log(Inventory);
Array.from(ItemGrid.children).forEach((element) => {
LoadOwnedTags(element);
});
}
if (Settings.EventItemsCatOn === true) {
EventItems()
EventItems();
}
});
const observer = new MutationObserver(async function (list) {
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'
ItemGrid.classList.add('itemgrid');
ItemGrid.parentElement.classList.remove('col-lg-9');
document.getElementById('pagination').style.display = 'block';
if (document.getElementById('storecat-eventitems') !== null) {
document.getElementById('storecat-eventitems').checked = false
document.getElementById('storecat-eventitems').checked = false;
}
} else {
ItemGrid.classList.remove('itemgrid')
ItemGrid.parentElement.classList.add('col-lg-9')
document.getElementById('pagination').style.display = 'none'
ItemGrid.classList.remove('itemgrid');
ItemGrid.parentElement.classList.add('col-lg-9');
document.getElementById('pagination').style.display = 'none';
}
}
for (const record of list) {
for (const element of record.addedNodes) {
if (element.tagName === "DIV" && element.classList.value === 'mb-3 itemCardCont') {
if (element.tagName === 'DIV' && element.classList.value === 'mb-3 itemCardCont') {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
LoadIRLPrices(element)
LoadIRLPrices(element);
}
if (Settings.StoreOwnTagOn === true && Inventory !== null) {
LoadOwnedTags(element)
LoadOwnedTags(element);
}
}
}
@ -70,105 +70,115 @@ const observer = new MutationObserver(async function (list){
observer.observe(ItemGrid, {attributes: false, childList: true, subtree: false});
async function LoadIRLPrices(element) {
if (element.tagName != "DIV" || element.querySelector('small.text-primary')) {return}
const Parent = element.getElementsByTagName('small')[1]
if (Parent.innerText !== "") {
const Span = document.createElement('span')
Span.classList = 'text-muted polyplus-price-tag'
Span.style = 'font-size: 0.7rem; font-weight: lighter;'
const Price = Parent.innerText.split(' ')[1]
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency)
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
Parent.appendChild(Span)
if (element.tagName != 'DIV' || element.querySelector('small.text-primary')) {
return;
}
const Parent = element.getElementsByTagName('small')[1];
if (Parent.innerText !== '') {
const Span = document.createElement('span');
Span.classList = 'text-muted polyplus-price-tag';
Span.style = 'font-size: 0.7rem; font-weight: lighter;';
const Price = Parent.innerText.split(' ')[1];
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency);
Span.innerText = '($' + IRLResult.result + ' ' + IRLResult.display + ')';
Parent.appendChild(Span);
}
}
function LoadOwnedTags(element) {
let Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]))
let Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]));
if (Item !== null) {
const Tag = document.createElement('span')
Tag.classList = `badge ${ (Item.asset.isLimited === false) ? 'bg-primary' : 'bg-warning' } polyplus-own-tag`
Tag.style = 'position: absolute;font-size: 0.9rem;top: 0px;left: 0px;padding: 5.5px;border-top-left-radius: var(--bs-border-radius-lg)!important;border-top-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 0.65rem;'
Tag.innerHTML = "<i class='fas fa-star'></i>"
element.getElementsByTagName('img')[0].parentElement.appendChild(Tag)
const Tag = document.createElement('span');
Tag.classList = `badge ${Item.asset.isLimited === false ? 'bg-primary' : 'bg-warning'} polyplus-own-tag`;
Tag.style =
'position: absolute;font-size: 0.9rem;top: 0px;left: 0px;padding: 5.5px;border-top-left-radius: var(--bs-border-radius-lg)!important;border-top-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 0.65rem;';
Tag.innerHTML = "<i class='fas fa-star'></i>";
element.getElementsByTagName('img')[0].parentElement.appendChild(Tag);
if (Item.asset.isLimited === true) {
Tag.setAttribute('data-bs-toggle', 'tooltip')
Tag.setAttribute('data-bs-title', '#' + Item.serial)
Tag.setAttribute('data-bs-toggle', 'tooltip');
Tag.setAttribute('data-bs-title', '#' + Item.serial);
Utilities.InjectResource('registerTooltips')
Utilities.InjectResource('registerTooltips');
}
}
}
function CheckInventory(id) {
let Item = null
Inventory.forEach(element => {
let Item = null;
Inventory.forEach((element) => {
if (element.asset.id === id) {
Item = element
Item = element;
}
})
return Item
});
return Item;
}
function EventItems() {
const Selector = document.createElement('div')
Selector.classList = 'form-check store-category-check fw-bold'
Selector.style.borderColor = '#B008B0'
const Selector = document.createElement('div');
Selector.classList = 'form-check store-category-check fw-bold';
Selector.style.borderColor = '#B008B0';
Selector.innerHTML = `
<input class="form-check-input" type="radio" name="storecat" id="storecat-eventitems">
<label class="form-check-label" for="storecat-eventitems">
<i class="fad fa-party-horn"></i> Event Items
</label>
`
`;
Categories.appendChild(Selector)
Categories.appendChild(Selector);
let EventData = null
let Events = []
let Groups = []
let Page = 0
let EventData = null;
let Events = [];
let Groups = [];
let Page = 0;
Selector.children[0].addEventListener('click', async function () {
Array.from(Categories.children).forEach(selector => {
selector.classList.remove('active')
})
Selector.classList.add('active')
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()
EventData = await (await fetch('https://polyplus.vercel.app/data/eventItems.json')).json();
Object.values(EventData.eventDetails).forEach((x, index) => {Events.push({
Object.values(EventData.eventDetails).forEach((x, index) => {
Events.push({
...x,
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))
Groups.push(Events.splice(0, 5));
}
}
ItemGrid.classList.remove('itemgrid')
ItemGrid.classList.remove('itemgrid');
ItemGrid.innerHTML = `
<div id="p+ei">
${
Groups[Page].map((x, index) => `
${Groups[Page].map(
(x, index) => `
<div class="row px-2 px-lg-0" style="animation-delay: 0.24s;">
<div class="col">
<h6 class="dash-ctitle2">${x.date}</h6>
<h5 class="dash-ctitle">${x.name}</h5>
</div>
${ (x.link !== undefined) ? `
${
x.link !== undefined
? `
<div class="col-auto d-flex align-items-center">
<a class="text-muted" href="${x.link}">
<span class="d-none d-lg-inline">${ (x.link.startsWith('https://polytoria.com/places/')) ? 'Event Place' : 'Blog Post' }</span>
<span class="d-none d-lg-inline">${x.link.startsWith('https://polytoria.com/places/') ? 'Event Place' : 'Blog Post'}</span>
<i class="fas fa-angle-right ms-2"></i>
</a>
</div>
` : '' }
`
: ''
}
</div>
<div class="card card-dash mcard mb-3" style="animation-delay: 0.27s;">
<div class="card-body p-0 m-1 scrollFadeContainer">
<div class="d-flex">
${
x.items.map((x) => `
${x.items
.map(
(x) => `
<a href="/store/${x.id}">
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
<div class="card-body">
@ -181,13 +191,14 @@ function EventItems() {
</div>
</div>
</a>
`).join('')
}
`
)
.join('')}
</div>
</div>
</div>
`).join('')
}
`
).join('')}
</div>
<div class="d-flex justify-content-center mt-3">
@ -214,62 +225,63 @@ function EventItems() {
</ul>
</nav>
</div>
`
`;
const Container = document.getElementById('p+ei')
const Pagination = document.getElementById('event-items-pagination')
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 Container = document.getElementById('p+ei');
const Pagination = document.getElementById('event-items-pagination');
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');
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
First.parentElement.classList.remove('disabled')
Prev.parentElement.classList.remove('disabled');
First.parentElement.classList.remove('disabled');
} else {
Prev.parentElement.classList.add('disabled')
First.parentElement.classList.add('disabled')
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')
Next.parentElement.classList.remove('disabled');
Last.parentElement.classList.remove('disabled');
} else {
Next.parentElement.classList.add('disabled')
Last.parentElement.classList.add('disabled')
Next.parentElement.classList.add('disabled');
Last.parentElement.classList.add('disabled');
}
First.addEventListener('click', function () {
if (Page > 0) {
Page = 0
UpdateEventItems()
Page = 0;
UpdateEventItems();
}
})
});
Prev.addEventListener('click', function () {
if (Page > 0) {
Page--
UpdateEventItems()
Page--;
UpdateEventItems();
}
})
});
Next.addEventListener('click', function () {
if (Page < Groups.length - 1) {
Page++
UpdateEventItems()
Page++;
UpdateEventItems();
}
})
});
Last.addEventListener('click', function () {
if (Page < Groups.length - 1) {
Page = Groups.length-1
UpdateEventItems()
Page = Groups.length - 1;
UpdateEventItems();
}
})
});
const UpdateEventItems = function () {
Current.innerText = Page+1
Container.innerHTML = Groups[Page].map((x, index) => `
Current.innerText = Page + 1;
Container.innerHTML = Groups[Page].map(
(x, index) => `
<div class="row px-2 px-lg-0" style="animation-delay: 0.24s;">
<div class="col">
<h6 class="dash-ctitle2">${x.date}</h6>
@ -279,8 +291,9 @@ function EventItems() {
<div class="card card-dash mcard mb-3" style="animation-delay: 0.27s;">
<div class="card-body p-0 m-1 scrollFadeContainer">
<div class="d-flex">
${
x.items.map((x) => `
${x.items
.map(
(x) => `
<a href="/store/${x.id}">
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
<div class="card-body">
@ -293,28 +306,30 @@ function EventItems() {
</div>
</div>
</a>
`).join('')
}
`
)
.join('')}
</div>
</div>
</div>
</div>
`).join('')
`
).join('');
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
First.parentElement.classList.remove('disabled')
Prev.parentElement.classList.remove('disabled');
First.parentElement.classList.remove('disabled');
} else {
Prev.parentElement.classList.add('disabled')
First.parentElement.classList.add('disabled')
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')
Next.parentElement.classList.remove('disabled');
Last.parentElement.classList.remove('disabled');
} else {
Next.parentElement.classList.add('disabled')
Last.parentElement.classList.add('disabled')
Next.parentElement.classList.add('disabled');
Last.parentElement.classList.add('disabled');
}
}
})
};
});
}

View file

@ -117,9 +117,7 @@
"service_worker": "/js/background.js",
"type": "module"
},
"host_permissions": [
"https://*.polytoria.com/*"
],
"host_permissions": ["https://*.polytoria.com/*"],
"web_accessible_resources": [
{
"resources": ["resources/*"],

View file

@ -28,7 +28,7 @@
<div class="card-body">
<iframe id="viewFrame" style="width: 100%; height: 314px; border-radius: 0.65rem;"></iframe>
<div id="options">
<input name="JSONUpload" type="file" accept="application/json" multiple="false" id="jsonUpload" aria-label="Upload JSON!" style="display: none;">
<input name="JSONUpload" type="file" accept="application/json" multiple="false" id="jsonUpload" aria-label="Upload JSON!" style="display: none;" />
<label for="JSONUpload" style="display: block;">
<button aria-label="Upload JSON!" onclick="this.parentElement.previousElementSibling.click()">
@ -65,7 +65,7 @@
</div>
</div>
<div class="input-group mb-3">
<input type="text" class="form-control bg-dark" placeholder="Asset ID..">
<input type="text" class="form-control bg-dark" placeholder="Asset ID.." />
<button class="btn btn-primary" id="load-asset">Load Asset</button>
</div>
<div class="card mcard mb-3">
@ -79,10 +79,13 @@
<button id="head" class="avatarAction bodypart bp1x1" style="background-color: #e0e0e0;"></button>
</div>
<div style="margin-bottom: 5px">
<button id="rightArm" class="avatarAction bodypart bp1x2" style="background-color: #e0e0e0; margin-right: 5px;"></button><button id="torso" class="avatarAction bodypart bp2x2" style="background-color: #e0e0e0;"></button><button class="avatarAction bodypart bp1x2" id="leftArm" style="background-color: #e0e0e0; margin-left: 5px;"></button>
<button id="rightArm" class="avatarAction bodypart bp1x2" style="background-color: #e0e0e0; margin-right: 5px;"></button
><button id="torso" class="avatarAction bodypart bp2x2" style="background-color: #e0e0e0;"></button
><button class="avatarAction bodypart bp1x2" id="leftArm" style="background-color: #e0e0e0; margin-left: 5px;"></button>
</div>
<div>
<button class="avatarAction bodypart bp1x2" id="rightLeg" style="background-color: #e0e0e0; margin-right: 5px; padding-right: 18px;"></button><button id="leftLeg" class="avatarAction bodypart bp1x2" style="background-color: #e0e0e0; padding-right: 18px;"></button>
<button class="avatarAction bodypart bp1x2" id="rightLeg" style="background-color: #e0e0e0; margin-right: 5px; padding-right: 18px;"></button
><button id="leftLeg" class="avatarAction bodypart bp1x2" style="background-color: #e0e0e0; padding-right: 18px;"></button>
</div>
</div>
</div>
@ -123,7 +126,7 @@
</li>
</ul>
<div class="card px-2 pt-2 pb-2 mb-4" style="background: rgba(0, 0, 0, 0.23); border-color: rgba(0, 0, 0, 0.23); border-top-left-radius: 20px; border-top-right-radius: 20px;">
<input id="item-search" type="text" class="form-control mb-2" placeholder="Search for an item...">
<input id="item-search" type="text" class="form-control mb-2" placeholder="Search for an item..." />
<div class="row alignleft itemgrid" id="inventory"></div>
</div>
<h6 class="card-header mb-2"><i class="fad fa-hat-wizard me-1"></i> Wearing</h6>

View file

@ -1,4 +1,7 @@
window.localStorage.setItem('p+account_info', JSON.stringify({
window.localStorage.setItem(
'p+account_info',
JSON.stringify({
ID: userID,
Bricks: document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g, '')
}))
})
);

View file

@ -1,2 +1,2 @@
var tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]')
var list = [...tooltips].map(tool => new bootstrap.Tooltip(tool))
var tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]');
var list = [...tooltips].map((tool) => new bootstrap.Tooltip(tool));

View file

@ -8,10 +8,16 @@ HOW TO USE IN CONTENT SCRIPTS:
*/
function ParseFullNumber(ab) {
if (typeof(ab) === "number") { return ab }
const Suffixes = {"k": 1000, "m": 1000000, "b": 1000000000}
if (typeof ab === 'number') {
return ab;
}
const Suffixes = {k: 1000, m: 1000000, b: 1000000000};
const Suffix = ab.slice(-1).toLowerCase();
if (Suffixes[Suffix]) {return parseFloat(ab)*Suffixes[Suffix]} else {return parseFloat(ab)}
if (Suffixes[Suffix]) {
return parseFloat(ab) * Suffixes[Suffix];
} else {
return parseFloat(ab);
}
}
export default {
@ -44,24 +50,24 @@ export default {
ModifyNavOn: false,
ModifyNav: [
{
Label: "Places",
Link: "https://polytoria.com/places"
Label: 'Places',
Link: 'https://polytoria.com/places'
},
{
Label: "Store",
Link: "https://polytoria.com/store"
Label: 'Store',
Link: 'https://polytoria.com/store'
},
{
Label: "Guilds",
Link: "https://polytoria.com/guilds"
Label: 'Guilds',
Link: 'https://polytoria.com/guilds'
},
{
Label: "People",
Link: "https://polytoria.com/users"
Label: 'People',
Link: 'https://polytoria.com/users'
},
{
Label: "Forum",
Link: "https://polytoria.com/forum"
Label: 'Forum',
Link: 'https://polytoria.com/forum'
}
],
MoreSearchFiltersOn: true,
@ -99,22 +105,8 @@ export default {
ImprovedFrLists: 20,
ItemWishlist: 20
},
MeshTypes: [
"hat",
"hair",
"head attachment",
"face accessory",
"neck accessory",
"head cover",
"back accessory",
"shoulder accessory",
"tool"
],
TextureTypes: [
"shirt",
"pants",
"face"
],
MeshTypes: ['hat', 'hair', 'head attachment', 'face accessory', 'neck accessory', 'head cover', 'back accessory', 'shoulder accessory', 'tool'],
TextureTypes: ['shirt', 'pants', 'face'],
CalculateIRL: async function (bricks, to, brickPackage) {
/*
Disabled for now: currency retrieval from currencies.json
@ -127,95 +119,97 @@ export default {
const UnitPrice = data.Data[brickPackage][to]
*/
let Icon = "$"
let Result = "N/A";
let Display = "Currency Not Found";
let Icon = '$';
let Result = 'N/A';
let Display = 'Currency Not Found';
// is the icon abbreviated text, or an entity
let IsIconAbbr = false
let IsIconAbbr = false;
bricks = ParseFullNumber(bricks.replace(/,/g, ''))
bricks = ParseFullNumber(bricks.replace(/,/g, ''));
switch (to) {
// U.S. Dollar
case 0:
Result = (bricks * 0.0099).toFixed(2)
Display = "USD"
Result = (bricks * 0.0099).toFixed(2);
Display = 'USD';
break
break;
// Euro
case 1:
Icon = "&#8364;"
Result = (bricks * 0.009).toFixed(2)
Display = "EUR"
Icon = '&#8364;';
Result = (bricks * 0.009).toFixed(2);
Display = 'EUR';
break
break;
// Canadian Dollar
case 2:
Icon = "CAD$"
IsIconAbbr = true
Icon = 'CAD$';
IsIconAbbr = true;
Result = (bricks * 0.0131).toFixed(2)
Display = "CAD"
Result = (bricks * 0.0131).toFixed(2);
Display = 'CAD';
break
break;
// Great British Pound
case 3:
Icon = "&#163;"
Result = (bricks * 0.0077).toFixed(2)
Display = "GBP"
Icon = '&#163;';
Result = (bricks * 0.0077).toFixed(2);
Display = 'GBP';
break
break;
// Mexican Peso
case 4:
Icon = "MXN$"
IsIconAbbr = true
Icon = 'MXN$';
IsIconAbbr = true;
Result = (bricks * 0.1691).toFixed(2)
Display = "MXN"
Result = (bricks * 0.1691).toFixed(2);
Display = 'MXN';
break
break;
// Australia Dollar
case 5:
Icon = "AU$"
IsIconAbbr = true
Icon = 'AU$';
IsIconAbbr = true;
Result = (bricks * 0.0144).toFixed(2)
Display = "AUD"
Result = (bricks * 0.0144).toFixed(2);
Display = 'AUD';
break
break;
// Turkish Lira
case 6:
Icon = "&#8378;"
Result = (bricks * 0.2338).toFixed(2)
Display = "TRY"
Icon = '&#8378;';
Result = (bricks * 0.2338).toFixed(2);
Display = 'TRY';
break
break;
// Brazillian Real
case 7:
Icon = "R$"
IsIconAbbr = true
Icon = 'R$';
IsIconAbbr = true;
Result = (bricks * 0.49).toFixed(2)
Display = "BRL"
Result = (bricks * 0.49).toFixed(2);
Display = 'BRL';
break
break;
}
if (typeof(Result) === "number") { Result = Result.toFixed(2) }
if (typeof Result === 'number') {
Result = Result.toFixed(2);
}
return {
result: Result,
display: Display,
icon: Icon,
isIconAbbr: IsIconAbbr
}
};
},
InjectResource: function (path, element) {
// Function by devjin0617 on GitHub
@ -223,12 +217,16 @@ export default {
// Slightly modified to use constants and fit the rest of the code style more
// Function only used for registering bootstrap tooltips currently
if (element === undefined) { element = 'body' }
if (element === undefined) {
element = 'body';
}
const Node = document.getElementsByTagName(element)[0];
const Script = document.createElement('script');
Script.setAttribute('type', 'text/javascript');
Script.setAttribute('src', chrome.runtime.getURL('resources/' + path + '.js'));
Script.addEventListener('load', function(){Script.remove()})
Script.addEventListener('load', function () {
Script.remove();
});
Node.appendChild(Script);
}
}
};

View file

@ -1,18 +1,20 @@
<html>
<head>
<!-- META TAGS -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- PUBLIC -->
<title>Poly+ Settings</title>
<!-- RESOURCES -->
<link rel="stylesheet" href="css/polytoria.css">
<link rel="stylesheet" href="css/polytoria.css" />
</head>
<body data-bs-theme="dark">
<style>
html, body, #page {
html,
body,
#page {
background: #202020;
color: #fff;
}
@ -128,53 +130,53 @@
</div>
<div class="modal-body">
<p>Let out your creativity and turn it into a reality on Polytoria's website!</p>
<hr class="mt-3 mb-3">
<hr class="mt-3 mb-3" />
<label>Save Theme to JSON</label>
<div class="input-group mb-3">
<input id="SaveThemeToJSONInput" type="text" class="form-control bg-dark ignore" placeholder="JSON String..." disabled>
<input id="SaveThemeToJSONInput" type="text" class="form-control bg-dark ignore" placeholder="JSON String..." disabled />
<button id="CopyThemeJSONBtn" class="btn btn-warning">Copy</button>
</div>
<label>Load Theme from JSON</label>
<div class="input-group">
<input type="text" class="form-control bg-dark ignore" placeholder="JSON...">
<input type="text" class="form-control bg-dark ignore" placeholder="JSON..." />
<button id="LoadThemeFromJSONBtn" class="btn btn-success ignore">Load</button>
</div>
<hr class="mt-2 mb-3">
<hr class="mt-2 mb-3" />
<div class="card mb-2">
<div class="card-header">Navigation</div>
<div class="card-body">
<label>Navbar Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavBGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavBGColor" />
<label>Navbar Border Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavBorderColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavBorderColor" />
<label>Sidebar Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideBGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideBGColor" />
<label>Sidebar Border Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideBorderColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideBorderColor" />
<hr class="navbar-divider">
<hr class="navbar-divider" />
<label>Navbar Item Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavItemColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="NavItemColor" />
<label>Sidebar Item Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemBGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemBGColor" />
<label>Sidebar Item Border Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemBorderColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemBorderColor" />
<label>Sidebar Item Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemColor" />
<label>Sidebar Item Label Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemLabelColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SideItemLabelColor" />
</div>
</div>
@ -182,10 +184,10 @@
<div class="card-header">Background</div>
<div class="card-body">
<label>Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="BGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="BGColor" />
<label>Background Image (URL)</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="BGImage">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="BGImage" />
<label>Background Image Size (if there is a background image)</label>
<select class="form-select bg-dark mb-2" data-setting="BGImageSize">
@ -200,10 +202,10 @@
<div class="card-header">Text</div>
<div class="card-body">
<label>Primary Text Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="PrimaryTextColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="PrimaryTextColor" />
<label>Secondary Text Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SecondaryTextColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="SecondaryTextColor" />
<div class="row">
<div class="col">
@ -218,9 +220,9 @@
</div>
<div class="input-group">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkTextColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkHoveredTextColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkFocusedTextColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkTextColor" />
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkHoveredTextColor" />
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="LinkFocusedTextColor" />
</div>
</div>
</div>
@ -229,13 +231,13 @@
<div class="card-header">Cards</div>
<div class="card-body">
<label>Card (Header) Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardHeadBGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardHeadBGColor" />
<label>Card (Body) Background Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardBodyBGColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardBodyBGColor" />
<label>Card Border Color</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardBorderColor">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="CardBorderColor" />
</div>
</div>
@ -243,7 +245,7 @@
<div class="card-header">Branding</div>
<div class="card-body">
<label>Website Logo (URL)</label>
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="WebsiteLogo">
<input class="form-control bg-dark mb-2" placeholder="..." data-setting="WebsiteLogo" />
</div>
</div>
@ -260,55 +262,55 @@
</div>
<div class="modal-body">
<p>Customize the navbar to your liking!</p>
<hr class="mt-2 mb-3">
<hr class="mt-2 mb-3" />
<div class="card mb-2">
<div class="card-header">#1 Navbar Item</div>
<div class="card-body">
<label>Label</label>
<input class="form-control bg-dark mb-2" placeholder="Play" data-parent="0" data-setting="Label">
<input class="form-control bg-dark mb-2" placeholder="Play" data-parent="0" data-setting="Label" />
<label>Link</label>
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/places/" data-parent="0" data-setting="Link">
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/places/" data-parent="0" data-setting="Link" />
</div>
</div>
<div class="card mb-2">
<div class="card-header">#2 Navbar Item</div>
<div class="card-body">
<label>Label</label>
<input class="form-control bg-dark mb-2" placeholder="Store" data-parent="1" data-setting="Label">
<input class="form-control bg-dark mb-2" placeholder="Store" data-parent="1" data-setting="Label" />
<label>Link</label>
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/store/" data-parent="1" data-setting="Link">
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/store/" data-parent="1" data-setting="Link" />
</div>
</div>
<div class="card mb-2">
<div class="card-header">#3 Navbar Item</div>
<div class="card-body">
<label>Label</label>
<input class="form-control bg-dark mb-2" placeholder="Guilds" data-parent="2" data-setting="Label">
<input class="form-control bg-dark mb-2" placeholder="Guilds" data-parent="2" data-setting="Label" />
<label>Link</label>
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/guilds/" data-parent="2" data-setting="Link">
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/guilds/" data-parent="2" data-setting="Link" />
</div>
</div>
<div class="card mb-2">
<div class="card-header">#4 Navbar Item</div>
<div class="card-body">
<label>Label</label>
<input class="form-control bg-dark mb-2" placeholder="People" data-parent="3" data-setting="Label">
<input class="form-control bg-dark mb-2" placeholder="People" data-parent="3" data-setting="Label" />
<label>Link</label>
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/users/" data-parent="3" data-setting="Link">
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/users/" data-parent="3" data-setting="Link" />
</div>
</div>
<div class="card mb-2">
<div class="card-header">#5 Navbar Item</div>
<div class="card-body">
<label>Label</label>
<input class="form-control bg-dark mb-2" placeholder="Forum" data-parent="4" data-setting="Label">
<input class="form-control bg-dark mb-2" placeholder="Forum" data-parent="4" data-setting="Label" />
<label>Link</label>
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/forum" data-parent="4" data-setting="Link">
<input class="form-control bg-dark mb-2" placeholder="https://polytoria.com/forum" data-parent="4" data-setting="Link" />
</div>
</div>
@ -327,7 +329,7 @@
Pinned Games
<button class="btn btn-sm toggle-btn" data-setting="PinnedGamesOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Pin your favorite places to the top of the homepage! (limit: <span id="PinnedGames-limit"></span> places)</span>
</p>
<p class="setting-container" id="forum-mentions">
@ -336,9 +338,9 @@
Forum Mentions
<button class="btn btn-sm toggle-btn" data-setting="ForumMentsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Get a quick link to the popular person everyone is talking about's profile!</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* Forum Mentions do not notify the user or show up as a notification on their account.</span>
</p>
<p class="setting-container" id="best-friends">
@ -347,7 +349,7 @@
Best Friends
<button class="btn btn-sm toggle-btn" data-setting="BestFriendsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Prioritize the bestest of friends on applicable friend lists! (limit: <span id="BestFriends-limit"></span> best friends)</span>
</p>
<p class="setting-container" id="improved-friend-lists">
@ -356,10 +358,10 @@
Improved Friend Lists
<button class="btn btn-sm toggle-btn" data-setting="ImprovedFrListsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">
Accept or decline all friend requests with the click of a button or multi-remove existing friends!
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* You can only remove up to <span id="ImprovedFrLists-limit"></span> friends at once.</span>
</span>
</p>
@ -369,12 +371,12 @@
Show IRL price with Brick Count
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="IRLPriceWithCurrency">Toggle</button>
</span>
<br>
<br />
<span class="desc mb-4">
See the real life currency value along with Bricks across the site!
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* Currencies were calculated on <span id="IRLPriceWithCurrency-Date">[DATE]</span>.</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* Currencies other than USD are purely approximations.</span>
</span>
<select id="IRLPriceWithCurrencyCurrency" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Currency" data-parent="IRLPriceWithCurrency">
@ -404,7 +406,7 @@
Hide Notification Badges
<button class="btn btn-sm toggle-btn" data-setting="HideNotifBadgesOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Hide the annoying red circles on the sidebar!</span>
</p>
<p class="setting-container" id="store-own-tag">
@ -413,7 +415,7 @@
Show "OWNED" Tag on Store Main Page
<button class="btn btn-sm toggle-btn" data-setting="StoreOwnTagOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Quickly see if you own the item at a glance with a little tag in the top left corner of item cards on the main store page!</span>
</p>
<p class="setting-container" id="theme-creator">
@ -423,7 +425,7 @@
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ThemeCreator">Toggle</button>
<button id="ThemeCreator-Options" class="btn btn-primary btn-sm" data-modal="ThemeCreator">Options</button>
</span>
<br>
<br />
<span class="desc">Unleash your creativity and customize the Polytoria website to your liking! (this feature is still in development)</span>
</p>
<p class="setting-container" id="more-search-filters">
@ -432,9 +434,9 @@
More Search Filters
<button class="btn btn-sm toggle-btn" data-setting="MoreSearchFiltersOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Easily find what you're looking for with more search filters side-wide! (this does not affect the main site search on the navbar)</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* This currently only has a "Creator" username filter on the forum search page, more search filters are yet to come.</span>
</p>
<p class="setting-container" id="apply-membership-theme">
@ -443,7 +445,7 @@
Apply Membership Theme for <b>Free</b>
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ApplyMembershipTheme">Toggle</button>
</span>
<br>
<br />
<span class="desc">Ever want the fancy membership themes for completely <b>free</b>? Well now you can get apply them site-wide!</span>
<select id="ApplyMembershipThemeTheme" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Theme" data-parent="ApplyMembershipTheme">
<option value="Plus" selected>Plus</option>
@ -456,10 +458,10 @@
Multi-Cancel Outbound Trades
<button class="btn btn-sm toggle-btn" data-setting="MultiCancelOutTradesOns">Toggle</button>
</span>
<br>
<br />
<span class="desc">
Quickly cancel several out-bound trades (trades that you have sent) all at once
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* You can only cancel up to 10 trades at once.</span>
</span>
</p>
@ -470,10 +472,8 @@
<button class="btn btn-sm toggle-btn" data-setting="ModifyNavOn">Toggle</button>
<button id="ModifyNav-Options" class="btn btn-primary btn-sm" data-modal="ModifyNav">Options</button>
</span>
<br>
<span class="desc">
Customize the navbar to your liking!
</span>
<br />
<span class="desc"> Customize the navbar to your liking! </span>
</p>
<p class="setting-container" id="item-wishlist">
<span class="indicator">&nbsp;</span>
@ -481,10 +481,8 @@
Item Wishlist
<button class="btn btn-sm toggle-btn" data-setting="ItemWishlistOn">Toggle</button>
</span>
<br>
<span class="desc">
Wishlist that item that you REALLY want!
</span>
<br />
<span class="desc"> Wishlist that item that you REALLY want! </span>
</p>
<!--
<p class="setting-container" id="hide-upgrade-button">
@ -503,7 +501,7 @@
Try-On Items
<button class="btn btn-sm toggle-btn" data-setting="TryOnItemsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">See how that new item looks on your avatar before spending your bricks!</span>
</p>
<p class="setting-container" id="outfit-cost">
@ -512,7 +510,7 @@
Show Outfit Cost on Profiles
<button class="btn btn-sm toggle-btn" data-setting="OutfitCostOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Quickly see how many bricks a user spent on their avatar!</span>
</p>
<p class="setting-container" id="outfit-cost">
@ -521,10 +519,12 @@
Show Approximate Place Revenue
<button class="btn btn-sm toggle-btn" data-setting="ShowPlaceRevenueOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Quickly see how many bricks a user has gained from one of their places!</span>
<br>
<span style="font-size: 0.8rem; color: orange;">* Gamepass revenue is calculated assuming the price hasn't changed and all users that bought the gamepass, bought it at the same price that it is at the time of calculating.</span>
<br />
<span style="font-size: 0.8rem; color: orange;"
>* Gamepass revenue is calculated assuming the price hasn't changed and all users that bought the gamepass, bought it at the same price that it is at the time of calculating.</span
>
</p>
<p class="setting-container" id="item-replace-sales">
<span class="indicator">&nbsp;</span>
@ -532,7 +532,7 @@
Show "Owners" instead of "Sales"
<button class="btn btn-sm toggle-btn" data-setting="ReplaceItemSalesOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Replace the "Sales" statistic with the "Owners" statistic if the item has 0 sales (most likely meaning it is an item awarded by staff).</span>
</p>
<p class="setting-container" id="hoarders-list">
@ -541,13 +541,13 @@
Collectibles' Hoarders List
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HoardersList">Toggle</button>
</span>
<br>
<br />
<span class="desc">List all the users that have more than 1 copy of a collectible!</span>
<span class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="hoarders-list-avatars" data-setting="AvatarsEnabled" data-parent="HoardersList">
<input class="form-check-input" type="checkbox" role="switch" id="hoarders-list-avatars" data-setting="AvatarsEnabled" data-parent="HoardersList" />
<label class="form-check-label" for="hoarders-list-avatars">
Show Avatar Icons
<br>
<br />
<span style="font-size: 0.6rem; color: orange;">* Avatar icons will result in more requests, potentially leading to more ratelimiting and slower hoarder list loading.</span>
</label>
</span>
@ -566,7 +566,7 @@
Quick Library Downloads
<button class="btn btn-sm toggle-btn" data-setting="LibraryDownloadsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Quickly download a model (as a <code>.ptmd</code> file), mesh, decal, or sound right from the page showing you details about the asset!</span>
</p>
<p class="setting-container" id="event-items-store">
@ -575,7 +575,7 @@
"Event Items" Store Category
<button class="btn btn-sm toggle-btn" data-setting="EventItemsCatOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">List all the on-going and past event items separated by their event with a store category!</span>
</p>
<p class="setting-container" id="event-items-store">
@ -584,7 +584,7 @@
Show Friend Count on Homepage
<button class="btn btn-sm toggle-btn" data-setting="HomeFriendCountOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">See how many friends you have on your homepage/dashboard, just scroll to the "friends" section and you'll see it next to the heading!</span>
</p>
<p class="setting-container" id="timed-item-owner-check">
@ -593,8 +593,11 @@
Timed-Item Owner Check
<button class="btn btn-sm toggle-btn" data-setting="ItemOwnerCheckOn">Toggle</button>
</span>
<br>
<span class="desc">Click the shopping bags icon in the bottom left-hand corner of the timed item's item thumbnail to toggle an input and a button. Then just enter someone's username and it'll tell you whether they own it or not and if so what serial!</span>
<br />
<span class="desc"
>Click the shopping bags icon in the bottom left-hand corner of the timed item's item thumbnail to toggle an input and a button. Then just enter someone's username and it'll tell you whether
they own it or not and if so what serial!</span
>
</p>
<p class="setting-container" id="hide-user-ads">
<span class="indicator">&nbsp;</span>
@ -602,39 +605,35 @@
Hide User Ads
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HideUserAds">Toggle</button>
</span>
<br>
<br />
<span class="desc">Hide those annoying <s>out of context Discord message</s> user ads!</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* Ads that are shown to help support Polytoria are not hidden.</span>
<span class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="hide-user-ads-banner" data-setting="Banners" data-parent="HideUserAds">
<label class="form-check-label" for="hide-user-ads-banner">
Hide Banner User Ads
</label>
<input class="form-check-input" type="checkbox" role="switch" id="hide-user-ads-banner" data-setting="Banners" data-parent="HideUserAds" />
<label class="form-check-label" for="hide-user-ads-banner"> Hide Banner User Ads </label>
</span>
<span class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="hide-user-ads-rectangle" data-setting="Rectangles" data-parent="HideUserAds">
<label class="form-check-label" for="hide-user-ads-rectangle">
Hide Rectangle User Ads
</label>
<input class="form-check-input" type="checkbox" role="switch" id="hide-user-ads-rectangle" data-setting="Rectangles" data-parent="HideUserAds" />
<label class="form-check-label" for="hide-user-ads-rectangle"> Hide Rectangle User Ads </label>
</span>
</p>
<div class="card">
<div class="card-body">
<h3>EXPERIMENTAL SETTINGS</h3>
<p>These features are a work in progress.</p>
<hr>
<hr />
<p class="setting-container" id="game-profiles">
<span class="indicator">&nbsp;</span>
<span class="title">
Game Profiles
<button class="btn btn-sm toggle-btn" data-setting="GameProfilesOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Traverse a place view page that matches a place's color palette!</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* Place creators must request a game profile for one to be made.</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* This feature will be expanded upon in the future.</span>
</p>
<p class="setting-container" id="inline-editing">
@ -643,11 +642,11 @@
Inline Editing
<button class="btn btn-sm toggle-btn" data-setting="InlineEditingOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Quickly edit your asset's details such as name and description on the same page as viewing the asset!</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* This feature currently only supports places.</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* This feature is not finished or polished.</span>
</p>
<p class="setting-container" id="forum-unix-timestamps">
@ -656,9 +655,9 @@
Forum Unix Timestamps
<button class="btn btn-sm toggle-btn" data-setting="ForumUnixStampsOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">See a date and time that is adjusted to everyone (who is using Poly+)'s local time</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* The styling for this feature is not yet done.</span>
</p>
<p class="setting-container" id="avatar-sandbox">
@ -667,14 +666,14 @@
Avatar Sandbox
<button class="btn btn-sm toggle-btn" data-setting="AvatarSandboxOn">Toggle</button>
</span>
<br>
<br />
<span class="desc">Create an avatar with all the item possibilities available to your heart's content!</span>
<br>
<br />
<span style="font-size: 0.8rem; color: orange;">* This feature is not polished - things like modifying avatar "Body Colors", pagination, outfits, etc haven't been added.</span>
</p>
</div>
</div>
<hr>
<hr />
<div class="btn-group w-100">
<button id="Save" class="btn btn-primary w-50" disabled="true">Save</button>
<button id="ResetDefaults" class="btn btn-warning w-50">Reset to Default Settings</button>
@ -683,7 +682,7 @@
<span></span>
|
<a id="check-for-updates"><b>Check for Updates</b></a>
<br>
<br />
made by <a href="https://polytoria.com/u/Index" target="_blank">Index</a> with the help of several contributors <3
</p>
</div>

View file

@ -1,5 +1,5 @@
const SaveBtn = document.getElementById('Save')
const Elements = Array.from(document.getElementsByClassName('setting-container'))
const SaveBtn = document.getElementById('Save');
const Elements = Array.from(document.getElementsByClassName('setting-container'));
var Settings;
var ExpectedSettings;
@ -7,33 +7,33 @@ var ExpectedSettings;
var Utilities;
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
Utilities = Utilities.default;
ExpectedSettings = Utilities.DefaultSettings
LoadCurrent()
ExpectedSettings = Utilities.DefaultSettings;
LoadCurrent();
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames
document.getElementById('BestFriends-limit').innerText = Utilities.Limits.BestFriends
document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists
document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames;
document.getElementById('BestFriends-limit').innerText = Utilities.Limits.BestFriends;
document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists;
document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist;
})();
// Handle buttons at the bottom of the page
document.getElementById('ResetDefaults').addEventListener('click', function () {
document.getElementById('ResetDefaults-Modal').showModal();
});
SaveBtn.addEventListener("click", function() {
SaveBtn.addEventListener('click', function () {
Save();
});
// Handle modal buttons for Reset Defaults modal
document.getElementById('ResetDefaults-Modal-Yes').addEventListener('click', function () {
Settings = ExpectedSettings
Save()
Settings = ExpectedSettings;
Save();
setTimeout(function () {
LoadCurrent();
document.getElementById('ResetDefaults-Modal').close();
}, 400)
}, 400);
});
document.getElementById('ResetDefaults-Modal-No').addEventListener('click', function () {
document.getElementById('ResetDefaults-Modal').close();
@ -50,16 +50,16 @@ window.onbeforeunload = function() {
*/
// Loop thru each setting container and handle toggling, selecting, opening modal, etc
Elements.forEach(element => {
let Button = element.getElementsByTagName('button')[0]
let Options = element.getElementsByTagName('button')[1]
let Select = element.getElementsByTagName('select') || []
Elements.forEach((element) => {
let Button = element.getElementsByTagName('button')[0];
let Options = element.getElementsByTagName('button')[1];
let Select = element.getElementsByTagName('select') || [];
//let Checkbox = element.getElementsByTagName('input') || []
//console.log(Checkbox)
if (Button) {
Button.addEventListener('click', function () {
ToggleSetting(Button.getAttribute('data-setting'), element)
ToggleSetting(Button.getAttribute('data-setting'), element);
/*
if (!(Button.getAttribute('data-parent'))) {
@ -106,35 +106,39 @@ Elements.forEach(element => {
if (Options) {
Options.addEventListener('click', function () {
let Modal = document.getElementById(Options.getAttribute('data-modal') + '-Modal')
let ModalButtons = Modal.getElementsByTagName('button')
let ModalInputs = Modal.getElementsByTagName('input')
let ModalSelect = Modal.getElementsByTagName('select')
let Modal = document.getElementById(Options.getAttribute('data-modal') + '-Modal');
let ModalButtons = Modal.getElementsByTagName('button');
let ModalInputs = Modal.getElementsByTagName('input');
let ModalSelect = Modal.getElementsByTagName('select');
Array.from(ModalButtons).forEach(btn => {
Array.from(ModalButtons).forEach((btn) => {
if (!(btn.getAttribute('data-ignore') === 'true')) {
btn.addEventListener('click', function () {
let Setting = btn.getAttribute('data-setting')
let Setting = btn.getAttribute('data-setting');
if (Setting === '[save]') {
Array.from(ModalInputs).forEach(input => {
Array.from(ModalInputs).forEach((input) => {
if (!(input.getAttribute('data-ignore') === 'true')) {
if (!(input.getAttribute('data-parent'))) {
Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] = input.value || null
if (!input.getAttribute('data-parent')) {
Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] = input.value || null;
} else {
let Parent = input.getAttribute('data-parent')
if (!isNaN(parseInt(Parent))) {Parent = parseInt(Parent)}
Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] = input.value || null
let Parent = input.getAttribute('data-parent');
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent);
}
Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] = input.value || null;
}
}
});
Array.from(ModalSelect).forEach(select => {
Array.from(ModalSelect).forEach((select) => {
if (!(select.getAttribute('data-ignore') === 'true')) {
if (!(select.getAttribute('data-parent'))) {
Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')] = select.selectedIndex
if (!select.getAttribute('data-parent')) {
Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')] = select.selectedIndex;
} else {
let Parent = input.getAttribute('data-parent')
if (!isNaN(parseInt(Parent))) {Parent = parseInt(Parent)}
Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')] = select.selectedIndex
let Parent = input.getAttribute('data-parent');
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent);
}
Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')] = select.selectedIndex;
}
}
});
@ -142,115 +146,127 @@ Elements.forEach(element => {
setTimeout(function () {
LoadCurrent();
Modal.close();
}, 400)
}, 400);
} else if (Setting === '[reset-default]') {
if (confirm("Are you sure you'd like to reset these options to their defaults?") === true) {
Settings[Modal.getAttribute('data-setting')] = ExpectedSettings[Modal.getAttribute('data-setting')]
Save()
Settings[Modal.getAttribute('data-setting')] = ExpectedSettings[Modal.getAttribute('data-setting')];
Save();
Modal.close();
}
} else if (Setting === '[cancel]') {
Modal.close();
} else {
if (!(btn.getAttribute('data-parent'))) {
ToggleSetting(Modal.getAttribute('data-setting')[btn.getAttribute('data-setting')], null)
if (!btn.getAttribute('data-parent')) {
ToggleSetting(Modal.getAttribute('data-setting')[btn.getAttribute('data-setting')], null);
} else {
let Parent = input.getAttribute('data-parent')
if (!isNaN(parseInt(Parent))) {Parent = parseInt(Parent)}
ToggleSetting(Modal.getAttribute('data-setting')[Parent][btn.getAttribute('data-setting')], null)
let Parent = input.getAttribute('data-parent');
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent);
}
ToggleSetting(Modal.getAttribute('data-setting')[Parent][btn.getAttribute('data-setting')], null);
}
}
});
}
});
Array.from(ModalInputs).forEach(input => {
Array.from(ModalInputs).forEach((input) => {
if (!(input.getAttribute('data-ignore') === 'true')) {
if (!(input.getAttribute('data-parent'))) {
if (Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] !== "undefined" && Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] !== undefined) {
input.value = Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')]
if (!input.getAttribute('data-parent')) {
if (
Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] !== 'undefined' &&
Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')] !== undefined
) {
input.value = Settings[Modal.getAttribute('data-setting')][input.getAttribute('data-setting')];
} else {
input.value = ''
input.value = '';
}
} else {
let Parent = input.getAttribute('data-parent')
if (Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] !== "undefined" && Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] !== undefined) {
if (!isNaN(parseInt(Parent))) {Parent = parseInt(Parent)}
input.value = Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')]
let Parent = input.getAttribute('data-parent');
if (
Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] !== 'undefined' &&
Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')] !== undefined
) {
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent);
}
input.value = Settings[Modal.getAttribute('data-setting')][Parent][input.getAttribute('data-setting')];
} else {
input.value = ''
input.value = '';
}
}
}
});
Array.from(ModalSelect).forEach(select => {
Array.from(ModalSelect).forEach((select) => {
if (!(select.getAttribute('data-ignore') === 'true')) {
if (!(select.getAttribute('data-parent'))) {
if (Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')] !== "undefined") {
select.selectedIndex = Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')]
if (!select.getAttribute('data-parent')) {
if (Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')] !== 'undefined') {
select.selectedIndex = Settings[Modal.getAttribute('data-setting')][select.getAttribute('data-setting')];
}
} else {
let Parent = input.getAttribute('data-parent')
if (Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')] !== "undefined") {
if (!isNaN(parseInt(Parent))) {Parent = parseInt(Parent)}
select.selectedIndex = Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')]
let Parent = input.getAttribute('data-parent');
if (Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')] !== 'undefined') {
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent);
}
select.selectedIndex = Settings[Modal.getAttribute('data-setting')][Parent][select.getAttribute('data-setting')];
}
}
}
});
Modal.showModal()
Modal.showModal();
});
}
if (Select.length > 0) {
Array.from(Select).forEach(element => {
Array.from(Select).forEach((element) => {
element.addEventListener('change', function () {
SetSetting(element.getAttribute('data-setting'), element, element.selectedIndex)
Save()
SetSetting(element.getAttribute('data-setting'), element, element.selectedIndex);
Save();
});
});
}
});
function LoadCurrent() {
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
Settings = MergeObjects(result.PolyPlus_Settings || ExpectedSettings, ExpectedSettings)
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = MergeObjects(result.PolyPlus_Settings || ExpectedSettings, ExpectedSettings);
console.log("Current: ", Settings)
console.log('Current: ', Settings);
Elements.forEach(element => {
const ToggleBtn = element.getElementsByClassName('toggle-btn')[0]
Elements.forEach((element) => {
const ToggleBtn = element.getElementsByClassName('toggle-btn')[0];
if (Settings[ToggleBtn.getAttribute('data-setting')] === true) {
element.classList.add('enabled')
ToggleBtn.innerText = 'Disable'
ToggleBtn.classList.add('btn-danger')
element.classList.add('enabled');
ToggleBtn.innerText = 'Disable';
ToggleBtn.classList.add('btn-danger');
} else {
element.classList.add('disabled')
ToggleBtn.innerText = 'Enable'
ToggleBtn.classList.add('btn-success')
element.classList.add('disabled');
ToggleBtn.innerText = 'Enable';
ToggleBtn.classList.add('btn-success');
}
let SelectInput = element.getElementsByTagName('select')[0]
let SelectInput = element.getElementsByTagName('select')[0];
if (SelectInput) {
SelectInput.selectedIndex = Settings[SelectInput.getAttribute('data-setting')]
SelectInput.selectedIndex = Settings[SelectInput.getAttribute('data-setting')];
}
});
});
}
function ToggleSetting(Name, Element, Parent) {
document.title = "*unsaved | Poly+ Settings"
document.title = '*unsaved | Poly+ Settings';
let Status;
if (!Parent) {
Status = Settings[Name]
Status = Settings[Name];
if (Settings[Name] === true) {
Settings[Name] = false;
} else {
Settings[Name] = true;
}
} else {
Status = Settings[Parent][Name]
Status = Settings[Parent][Name];
if (Settings[Parent][Name] === true) {
Settings[Parent][Name] = false;
} else {
@ -258,85 +274,89 @@ function ToggleSetting(Name, Element, Parent) {
}
}
if (Element !== null) {
const ToggleBtn = Element.getElementsByClassName('toggle-btn')[0]
const ToggleBtn = Element.getElementsByClassName('toggle-btn')[0];
if (Status === false) {
ToggleBtn.innerText = 'Enable'
ToggleBtn.innerText = 'Enable';
} else {
ToggleBtn.innerText = 'Disable'
ToggleBtn.innerText = 'Disable';
}
Element.classList.toggle('enabled')
Element.classList.toggle('disabled')
ToggleBtn.classList.toggle('btn-success')
ToggleBtn.classList.toggle('btn-danger')
Element.classList.toggle('enabled');
Element.classList.toggle('disabled');
ToggleBtn.classList.toggle('btn-success');
ToggleBtn.classList.toggle('btn-danger');
}
if (SaveBtn.getAttribute('disabled')) {
SaveBtn.removeAttribute('disabled')
SaveBtn.removeAttribute('disabled');
}
}
function SetSetting(Name, Element, Value) {
console.log(Settings)
Settings[Name] = Value
console.log(Settings);
Settings[Name] = Value;
if (SaveBtn.getAttribute('disabled')) {
SaveBtn.removeAttribute('disabled')
SaveBtn.removeAttribute('disabled');
}
}
function Save() {
document.title = 'Poly+ Settings'
SaveBtn.setAttribute('disabled', 'true')
chrome.storage.sync.set({ 'PolyPlus_Settings': Settings, arrayOrder: true }, function() {
document.title = 'Poly+ Settings';
SaveBtn.setAttribute('disabled', 'true');
chrome.storage.sync.set({PolyPlus_Settings: Settings, arrayOrder: true}, function () {
console.log('Saved successfully!');
});
console.log("Save:", Settings);
console.log('Save:', Settings);
}
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn')
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput')
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn')
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn');
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput');
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn');
LoadThemeFromJSONBtn.addEventListener('click', function () {
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value)
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value);
});
document.getElementById('theme-creator').getElementsByTagName('button')[1].addEventListener('click', function(){
SaveThemeToJSONInput.value = JSON.stringify(Settings.ThemeCreator)
document
.getElementById('theme-creator')
.getElementsByTagName('button')[1]
.addEventListener('click', function () {
SaveThemeToJSONInput.value = JSON.stringify(Settings.ThemeCreator);
});
CopyThemeJSONBtn.addEventListener('click', function () {
if (SaveThemeToJSONInput.value.length > 0) {
navigator.clipboard.writeText(SaveThemeToJSONInput.value)
navigator.clipboard
.writeText(SaveThemeToJSONInput.value)
.then(() => {
alert('Successfully copied theme data to clipboard!')
alert('Successfully copied theme data to clipboard!');
})
.catch(() => {
alert('Failure to copy theme data to clipboard.')
alert('Failure to copy theme data to clipboard.');
});
}
});
function LoadThemeJSON(string) {
try {
let JSONTable = JSON.parse(string)
let JSONTable = JSON.parse(string);
if (JSONTable.length === ExpectedSettings.ThemeCreator.length) {
if (confirm('Are you sure you\'d like to replace this theme with the theme specified in the JSON?') === true) {
LoadThemeFromJSONBtn.previousElementSibling.value = ''
document.getElementById('ThemeCreator-Modal').close()
if (confirm("Are you sure you'd like to replace this theme with the theme specified in the JSON?") === true) {
LoadThemeFromJSONBtn.previousElementSibling.value = '';
document.getElementById('ThemeCreator-Modal').close();
for (let i = 0; i < JSONTable.length; i++) {
if (JSONTable[i][0] !== "#") {
JSONTable[i] = ""
if (JSONTable[i][0] !== '#') {
JSONTable[i] = '';
}
}
Settings.ThemeCreator = MergeObjects(JSONTable, ExpectedSettings.ThemeCreator)
Settings.ThemeCreator = MergeObjects(JSONTable, ExpectedSettings.ThemeCreator);
Save();
console.log(JSONTable.length, JSONTable, 'applied')
console.log(JSONTable.length, JSONTable, 'applied');
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].click();
}
} else {
alert('JSON is not a theme!')
alert('JSON is not a theme!');
}
} catch (error) {
alert('JSON is invalid!')
alert('JSON is invalid!');
}
}
@ -360,63 +380,72 @@ function MergeObjects(obj1, obj2) {
}
function FormatBool(bool) {
if (bool === true) { return 'enabled' }
else { return 'disabled' }
}
const Manifest = chrome.runtime.getManifest()
let BuildType = "Stable"
if (Manifest.version_name !== undefined) {BuildType = "Pre-Release"}
const FooterText = document.getElementById('footer-text')
FooterText.children[0].innerHTML = `Version: v${Manifest.version} | Build Type: ${BuildType}`
const CheckForUpdatesButton = document.getElementById('check-for-updates')
function CheckForUpdates() {
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates)
CheckForUpdatesButton.disabled = true
fetch('https://polyplus.vercel.app/data/version.json')
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
if (data.version === Manifest.version || Math.floor((data.version - Manifest.version) * 10) === 0) {
CheckForUpdatesButton.innerHTML = '<b>No updates available</b>'
alert('No updates available')
if (bool === true) {
return 'enabled';
} else {
const NumberOfUpdatesAvailable = Math.floor((data.version - Version) * 10)
CheckForUpdatesButton.innerHTML = '<b>'+NumberOfUpdatesAvailable+' update(s) available</b>'
alert(NumberOfUpdatesAvailable + ' updates available')
return 'disabled';
}
}
const Manifest = chrome.runtime.getManifest();
let BuildType = 'Stable';
if (Manifest.version_name !== undefined) {
BuildType = 'Pre-Release';
}
const FooterText = document.getElementById('footer-text');
FooterText.children[0].innerHTML = `Version: v${Manifest.version} | Build Type: ${BuildType}`;
const CheckForUpdatesButton = document.getElementById('check-for-updates');
function CheckForUpdates() {
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates);
CheckForUpdatesButton.disabled = true;
fetch('https://polyplus.vercel.app/data/version.json')
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then((data) => {
if (data.version === Manifest.version || Math.floor((data.version - Manifest.version) * 10) === 0) {
CheckForUpdatesButton.innerHTML = '<b>No updates available</b>';
alert('No updates available');
} else {
const NumberOfUpdatesAvailable = Math.floor((data.version - Version) * 10);
CheckForUpdatesButton.innerHTML = '<b>' + NumberOfUpdatesAvailable + ' update(s) available</b>';
alert(NumberOfUpdatesAvailable + ' updates available');
}
})
.catch(error => {console.log(error)});
.catch((error) => {
console.log(error);
});
}
CheckForUpdatesButton.addEventListener('click', CheckForUpdates)
CheckForUpdatesButton.addEventListener('click', CheckForUpdates);
fetch(chrome.runtime.getURL('resources/currencies.json'))
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
const DateText = new Date(data.Date).toLocaleDateString("en-US", {day:"numeric",month:"long",year:"numeric"})
document.getElementById('IRLPriceWithCurrency-Date').innerText = DateText
.then((data) => {
const DateText = new Date(data.Date).toLocaleDateString('en-US', {day: 'numeric', month: 'long', year: 'numeric'});
document.getElementById('IRLPriceWithCurrency-Date').innerText = DateText;
})
.catch(error => {console.log(error)})
.catch((error) => {
console.log(error);
});
chrome.storage.local.get(['PolyPlus_OutOfDate', 'PolyPlus_LiveVersion', 'PolyPlus_ReleaseNotes', 'PolyPlus_SkipUpdate'], function (result) {
const OutOfDate = result.PolyPlus_OutOfDate || false
const SkipUpdate = result.PolyPlus_SkipUpdate || null
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version
const OutOfDate = result.PolyPlus_OutOfDate || false;
const SkipUpdate = result.PolyPlus_SkipUpdate || null;
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version;
if (OutOfDate === true && SkipUpdate !== LiveVersion) {
const Banner = document.createElement('div')
Banner.classList = 'alert position-sticky p-3'
Banner.style = 'top: 30px; box-shadow: 0 0 20px 2px #000; z-index: 2000; background: rgb(163 39 39);'
const Banner = document.createElement('div');
Banner.classList = 'alert position-sticky p-3';
Banner.style = 'top: 30px; box-shadow: 0 0 20px 2px #000; z-index: 2000; background: rgb(163 39 39);';
Banner.innerHTML = `
<b>New Update Available!</b>
<br>
@ -426,15 +455,15 @@ chrome.storage.local.get(['PolyPlus_OutOfDate', 'PolyPlus_LiveVersion', 'PolyPlu
<a href="${result.PolyPlus_ReleaseNotes}" class="btn btn-primary btn-sm w-25" target="_blank">Go to Release Notes</a>
<button id="skip-this-update" class="btn btn-warning btn-sm w-25">(Not Recommended) Skip this Update</button>
</div>
`
document.getElementById('page').insertBefore(Banner, document.getElementById('page').children[1])
`;
document.getElementById('page').insertBefore(Banner, document.getElementById('page').children[1]);
const SkipButton = document.getElementById('skip-this-update')
const SkipButton = document.getElementById('skip-this-update');
SkipButton.addEventListener('click', function () {
Banner.remove()
chrome.storage.local.set({'PolyPlus_SkipUpdate': result.PolyPlus_LiveVersion}, function(){
console.log('set skip update to live version: ', result.PolyPlus_LiveVersion)
})
Banner.remove();
chrome.storage.local.set({PolyPlus_SkipUpdate: result.PolyPlus_LiveVersion}, function () {
console.log('set skip update to live version: ', result.PolyPlus_LiveVersion);
});
});
}
})
});

View file

@ -1,36 +1,36 @@
const SaveBtn = document.getElementById('Save')
const Elements = Array.from(document.getElementsByClassName('setting-container'))
const SaveBtn = document.getElementById('Save');
const Elements = Array.from(document.getElementsByClassName('setting-container'));
var Settings;
var Utilities;
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
LoadCurrent()
Utilities = Utilities.default;
LoadCurrent();
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames
document.getElementById('BestFriends-limit').innerText = Utilities.Limits.BestFriends
document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists
document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames;
document.getElementById('BestFriends-limit').innerText = Utilities.Limits.BestFriends;
document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists;
document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist;
})();
// Handle buttons at the bottom of the page
document.getElementById('ResetDefaults').addEventListener('click', function () {
document.getElementById('ResetDefaults-Modal').showModal();
});
SaveBtn.addEventListener("click", function() {
SaveBtn.addEventListener('click', function () {
Save();
});
// Handle modal buttons for Reset Defaults modal
document.getElementById('ResetDefaults-Modal-Yes').addEventListener('click', function () {
Settings = Utilities.DefaultSettings
Save()
Settings = Utilities.DefaultSettings;
Save();
setTimeout(function () {
LoadCurrent();
document.getElementById('ResetDefaults-Modal').close();
}, 400)
}, 400);
});
document.getElementById('ResetDefaults-Modal-No').addEventListener('click', function () {
document.getElementById('ResetDefaults-Modal').close();
@ -39,73 +39,81 @@ document.getElementById('ResetDefaults-Modal-No').addEventListener('click', func
// Handle leaving the settings page before saving
window.onbeforeunload = function () {
if (SaveBtn.getAttribute('disabled') !== undefined) {
return "Are you sure you'd like to leave? Your Poly+ settings haven't been saved."
}
return "Are you sure you'd like to leave? Your Poly+ settings haven't been saved.";
}
};
// Loop thru each setting container and handle toggling, selecting, opening modal, etc
Elements.forEach(element => {
console.log('Handle Element', element)
let Button = element.getElementsByTagName('button')[0]
let Options = element.getElementsByTagName('button')[1]
let Select = element.getElementsByTagName('select')[0]
let Checkbox = element.getElementsByTagName('input')[0]
Elements.forEach((element) => {
console.log('Handle Element', element);
let Button = element.getElementsByTagName('button')[0];
let Options = element.getElementsByTagName('button')[1];
let Select = element.getElementsByTagName('select')[0];
let Checkbox = element.getElementsByTagName('input')[0];
if (Button) {
Button.addEventListener('click', function () {
SetSetting(Button, "bool")
SetSetting(Button, 'bool');
});
}
if (Select) {
Select.addEventListener('change', function () {
if (Select.getAttribute('data-useValue') !== undefined) {
let Value = Select.options[Select.selectedIndex].value
if (!isNaN(Value)) { Value = parseInt(Value) }
SetSetting(Select, Value, false)
} else {
SetSetting(Select, Select.selectedIndex, false)
let Value = Select.options[Select.selectedIndex].value;
if (!isNaN(Value)) {
Value = parseInt(Value);
}
})
SetSetting(Select, Value, false);
} else {
SetSetting(Select, Select.selectedIndex, false);
}
});
}
if (Checkbox) {
Checkbox.addEventListener('change', function () {
SetSetting(Checkbox, Checkbox.checked, false)
})
SetSetting(Checkbox, Checkbox.checked, false);
});
}
if (Options) {
const Modal = document.getElementById(Options.getAttribute('data-modal') + '-Modal')
const ModalButtons = Modal.getElementsByTagName('button')
const ModalInputs = Modal.getElementsByTagName('input')
const ModalSelect = Modal.getElementsByTagName('select')
const Modal = document.getElementById(Options.getAttribute('data-modal') + '-Modal');
const ModalButtons = Modal.getElementsByTagName('button');
const ModalInputs = Modal.getElementsByTagName('input');
const ModalSelect = Modal.getElementsByTagName('select');
Options.addEventListener('click', function () {
Array.from(ModalButtons).filter((x) => !x.classList.contains('ignore')).forEach(button => {
Array.from(ModalButtons)
.filter((x) => !x.classList.contains('ignore'))
.forEach((button) => {
button.addEventListener('click', function () {
const Setting = button.getAttribute('data-setting')
const Setting = button.getAttribute('data-setting');
if (Setting === '[save]') {
// Save Modal Button
Array.from(ModalInputs).filter((x) => !x.classList.contains('ignore')).forEach(input => {
SetSetting(input, input.value, false, Modal.getAttribute('data-setting'))
Array.from(ModalInputs)
.filter((x) => !x.classList.contains('ignore'))
.forEach((input) => {
SetSetting(input, input.value, false, Modal.getAttribute('data-setting'));
});
Array.from(ModalSelect).filter((x) => !x.classList.contains('ignore')).forEach(select => {
SetSetting(select, select.selectedIndex, false, Modal.getAttribute('data-setting'))
Array.from(ModalSelect)
.filter((x) => !x.classList.contains('ignore'))
.forEach((select) => {
SetSetting(select, select.selectedIndex, false, Modal.getAttribute('data-setting'));
});
Save();
setTimeout(function () {
LoadCurrent();
Modal.close();
}, 400)
}, 400);
} else if (Setting === '[reset-default]') {
// Reset to Defaults Modal Button
if (confirm("Are you sure you'd like to reset these options to their defaults?") === true) {
Settings[Modal.getAttribute('data-setting')] = Utilities.DefaultSettings[Modal.getAttribute('data-setting')]
Save()
Settings[Modal.getAttribute('data-setting')] = Utilities.DefaultSettings[Modal.getAttribute('data-setting')];
Save();
Modal.close();
}
} else if (Setting === '[cancel]') {
@ -115,94 +123,99 @@ Elements.forEach(element => {
} else {
// Default Toggle Button
SetSetting(button, "bool", false, Modal.getAttribute('data-setting'))
SetSetting(button, 'bool', false, Modal.getAttribute('data-setting'));
}
})
})
});
});
Array.from(ModalInputs).filter((x) => !x.classList.contains('ignore')).forEach(input => {
const Status = GetSettingValue(input, Modal.getAttribute('data-setting'))
if (Status !== "undefined" && Status !== undefined) {
input.value = Status
Array.from(ModalInputs)
.filter((x) => !x.classList.contains('ignore'))
.forEach((input) => {
const Status = GetSettingValue(input, Modal.getAttribute('data-setting'));
if (Status !== 'undefined' && Status !== undefined) {
input.value = Status;
} else {
input.value = ''
input.value = '';
}
});
Array.from(ModalSelect).filter((x) => !x.classList.contains('ignore')).forEach(select => {
const Status = GetSettingValue(select, Modal.getAttribute('data-setting'))
if (Status !== "undefined" && Status !== undefined) {
select.selectedIndex = Status
Array.from(ModalSelect)
.filter((x) => !x.classList.contains('ignore'))
.forEach((select) => {
const Status = GetSettingValue(select, Modal.getAttribute('data-setting'));
if (Status !== 'undefined' && Status !== undefined) {
select.selectedIndex = Status;
}
});
Modal.showModal()
})
Modal.showModal();
});
}
});
function LoadCurrent() {
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
Settings = MergeObjects(result.PolyPlus_Settings || Utilities.DefaultSettings, Utilities.DefaultSettings)
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
Settings = MergeObjects(result.PolyPlus_Settings || Utilities.DefaultSettings, Utilities.DefaultSettings);
console.log("Current Settings: ", Settings)
console.log('Current Settings: ', Settings);
Elements.forEach(element => {
console.log('For Each Update')
UpdateElementState(element)
Elements.forEach((element) => {
console.log('For Each Update');
UpdateElementState(element);
});
});
}
function SetSetting(element, value, update, modalParent) {
const name = element.getAttribute('data-setting')
let parent = element.getAttribute('data-parent')
const name = element.getAttribute('data-setting');
let parent = element.getAttribute('data-parent');
if (modalParent !== undefined) {
console.log(modalParent)
parent = modalParent
console.log(modalParent);
parent = modalParent;
}
if (value === "bool") {
value = !GetSettingValue(element, modalParent)
if (value === 'bool') {
value = !GetSettingValue(element, modalParent);
}
if (parent !== null) {
let Parent = Object.values(Settings)[Object.keys(Settings).indexOf(parent)]
let Parent = Object.values(Settings)[Object.keys(Settings).indexOf(parent)];
if (!isNaN(element.getAttribute('data-parent')) && element.getAttribute('data-parent') !== null) {
console.log('is numbere!!!!')
Parent = Parent[parseInt(element.getAttribute('data-parent'))]
console.log('is numbere!!!!');
Parent = Parent[parseInt(element.getAttribute('data-parent'))];
}
Parent[name] = value
Parent[name] = value;
} else {
Settings[name] = value
Settings[name] = value;
}
if (update !== false) {
UpdateElementState(document.querySelector(`.setting-container:has([data-setting="${name}"])${ (parent !== null) ? `:has([data-parent="${parent}"])` : '' }`), value)
UpdateElementState(document.querySelector(`.setting-container:has([data-setting="${name}"])${parent !== null ? `:has([data-parent="${parent}"])` : ''}`), value);
}
if (SaveBtn.getAttribute('disabled')) {
SaveBtn.removeAttribute('disabled')
SaveBtn.removeAttribute('disabled');
}
const getInObject = function(a, b) { return Object.values(a)[Object.keys(a).indexOf(b)] }
const getInObject = function (a, b) {
return Object.values(a)[Object.keys(a).indexOf(b)];
};
}
function GetSettingValue(element, modalParent) {
const name = element.getAttribute('data-setting')
let parent = element.getAttribute('data-parent')
const name = element.getAttribute('data-setting');
let parent = element.getAttribute('data-parent');
if (modalParent !== undefined) {
parent = modalParent
parent = modalParent;
}
let Status = name;
if (parent !== null) {
let Parent = Object.values(Settings)[Object.keys(Settings).indexOf(parent)]
let Parent = Object.values(Settings)[Object.keys(Settings).indexOf(parent)];
if (!isNaN(element.getAttribute('data-parent')) && element.getAttribute('data-parent') !== null) {
Parent = Parent[parseInt(element.getAttribute('data-parent'))]
Status = Parent[name]
Parent = Parent[parseInt(element.getAttribute('data-parent'))];
Status = Parent[name];
} else {
Status = Object.values(Parent)[Object.keys(Parent).indexOf(name)]
Status = Object.values(Parent)[Object.keys(Parent).indexOf(name)];
}
/*
@ -212,108 +225,112 @@ function GetSettingValue(element, modalParent) {
Status = Object.values(Parent)[Object.keys(Parent).indexOf(Status)]
*/
} else {
Status = Settings[Status]
Status = Settings[Status];
}
console.log('Get Value Result', Status)
console.log('Get Value Result', Status);
return Status
return Status;
}
function UpdateElementState(element, status) {
console.log('Update Element State', element, status)
console.log('Update Element State', element, status);
const Button = element.getElementsByClassName('toggle-btn')[0]
const Button = element.getElementsByClassName('toggle-btn')[0];
if (status === undefined) {
console.log('Update Element State, no status provided')
status = GetSettingValue(Button)
console.log('Update Element State, no status provided');
status = GetSettingValue(Button);
}
if (status === true) {
console.log('Is Enabled so Set False')
element.classList.add('enabled')
element.classList.remove('disabled')
Button.innerText = 'Disable'
Button.classList.add('btn-danger')
Button.classList.remove('btn-success')
console.log('Is Enabled so Set False');
element.classList.add('enabled');
element.classList.remove('disabled');
Button.innerText = 'Disable';
Button.classList.add('btn-danger');
Button.classList.remove('btn-success');
} else {
console.log('Is Disabled so Set True')
element.classList.add('disabled')
element.classList.remove('enabled')
Button.innerText = 'Enable'
Button.classList.add('btn-success')
Button.classList.remove('btn-danger')
console.log('Is Disabled so Set True');
element.classList.add('disabled');
element.classList.remove('enabled');
Button.innerText = 'Enable';
Button.classList.add('btn-success');
Button.classList.remove('btn-danger');
}
let SelectInput = element.getElementsByTagName('select')[0]
let SelectInput = element.getElementsByTagName('select')[0];
if (SelectInput) {
console.log('Select Found')
SelectInput.selectedIndex = GetSettingValue(SelectInput)
console.log('Select Found');
SelectInput.selectedIndex = GetSettingValue(SelectInput);
}
let Checkbox = Array.from(element.getElementsByTagName('input'))
let Checkbox = Array.from(element.getElementsByTagName('input'));
if (Checkbox.length > 0) {
console.log('Checkbox/Input(s) Found', Checkbox)
Checkbox.forEach(check => {
console.log('check', GetSettingValue(check))
check.checked = GetSettingValue(check)
})
console.log('Checkbox/Input(s) Found', Checkbox);
Checkbox.forEach((check) => {
console.log('check', GetSettingValue(check));
check.checked = GetSettingValue(check);
});
}
}
function Save() {
document.title = 'Poly+ Settings'
SaveBtn.setAttribute('disabled', 'true')
chrome.storage.sync.set({ 'PolyPlus_Settings': Settings, arrayOrder: true }, function() {
document.title = 'Poly+ Settings';
SaveBtn.setAttribute('disabled', 'true');
chrome.storage.sync.set({PolyPlus_Settings: Settings, arrayOrder: true}, function () {
console.log('Saved successfully!');
});
console.log("Save:", Settings);
console.log('Save:', Settings);
}
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn')
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput')
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn')
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn');
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput');
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn');
LoadThemeFromJSONBtn.addEventListener('click', function () {
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value)
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value);
});
document.getElementById('theme-creator').getElementsByTagName('button')[1].addEventListener('click', function(){
SaveThemeToJSONInput.value = JSON.stringify(Settings.ThemeCreator)
document
.getElementById('theme-creator')
.getElementsByTagName('button')[1]
.addEventListener('click', function () {
SaveThemeToJSONInput.value = JSON.stringify(Settings.ThemeCreator);
});
CopyThemeJSONBtn.addEventListener('click', function () {
if (SaveThemeToJSONInput.value.length > 0) {
navigator.clipboard.writeText(SaveThemeToJSONInput.value)
navigator.clipboard
.writeText(SaveThemeToJSONInput.value)
.then(() => {
alert('Successfully copied theme data to clipboard!')
alert('Successfully copied theme data to clipboard!');
})
.catch(() => {
alert('Failure to copy theme data to clipboard.')
alert('Failure to copy theme data to clipboard.');
});
}
});
function LoadThemeJSON(string) {
try {
let JSONTable = JSON.parse(string)
let JSONTable = JSON.parse(string);
if (JSONTable.length === Utilities.DefaultSettings.ThemeCreator.length) {
if (confirm('Are you sure you\'d like to replace this theme with the theme specified in the JSON?') === true) {
LoadThemeFromJSONBtn.previousElementSibling.value = ''
document.getElementById('ThemeCreator-Modal').close()
if (confirm("Are you sure you'd like to replace this theme with the theme specified in the JSON?") === true) {
LoadThemeFromJSONBtn.previousElementSibling.value = '';
document.getElementById('ThemeCreator-Modal').close();
for (let i = 0; i < JSONTable.length; i++) {
if (JSONTable[i][0] !== "#") {
JSONTable[i] = ""
if (JSONTable[i][0] !== '#') {
JSONTable[i] = '';
}
}
Settings.ThemeCreator = MergeObjects(JSONTable, Utilities.DefaultSettings.ThemeCreator)
Settings.ThemeCreator = MergeObjects(JSONTable, Utilities.DefaultSettings.ThemeCreator);
Save();
console.log(JSONTable.length, JSONTable, 'applied')
console.log(JSONTable.length, JSONTable, 'applied');
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].click();
}
} else {
alert('JSON is not a theme!')
alert('JSON is not a theme!');
}
} catch (error) {
alert('JSON is invalid!')
alert('JSON is invalid!');
}
}
@ -337,63 +354,72 @@ function MergeObjects(obj1, obj2) {
}
function FormatBool(bool) {
if (bool === true) { return 'enabled' }
else { return 'disabled' }
}
const Manifest = chrome.runtime.getManifest()
let BuildType = "Stable"
if (Manifest.version_name !== undefined) {BuildType = "Pre-Release"}
const FooterText = document.getElementById('footer-text')
FooterText.children[0].innerHTML = `Version: v${Manifest.version} | Build Type: ${BuildType}`
const CheckForUpdatesButton = document.getElementById('check-for-updates')
function CheckForUpdates() {
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates)
CheckForUpdatesButton.disabled = true
fetch('https://polyplus.vercel.app/data/version.json')
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
return response.json()
})
.then(data => {
if (data.version === Manifest.version || Math.floor((data.version - Manifest.version) * 10) === 0) {
CheckForUpdatesButton.innerHTML = '<b>No updates available</b>'
alert('No updates available')
if (bool === true) {
return 'enabled';
} else {
const NumberOfUpdatesAvailable = Math.floor((data.version - Version) * 10)
CheckForUpdatesButton.innerHTML = '<b>'+NumberOfUpdatesAvailable+' update(s) available</b>'
alert(NumberOfUpdatesAvailable + ' updates available')
return 'disabled';
}
}
const Manifest = chrome.runtime.getManifest();
let BuildType = 'Stable';
if (Manifest.version_name !== undefined) {
BuildType = 'Pre-Release';
}
const FooterText = document.getElementById('footer-text');
FooterText.children[0].innerHTML = `Version: v${Manifest.version} | Build Type: ${BuildType}`;
const CheckForUpdatesButton = document.getElementById('check-for-updates');
function CheckForUpdates() {
CheckForUpdatesButton.removeEventListener('click', CheckForUpdates);
CheckForUpdatesButton.disabled = true;
fetch('https://polyplus.vercel.app/data/version.json')
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok');
}
return response.json();
})
.then((data) => {
if (data.version === Manifest.version || Math.floor((data.version - Manifest.version) * 10) === 0) {
CheckForUpdatesButton.innerHTML = '<b>No updates available</b>';
alert('No updates available');
} else {
const NumberOfUpdatesAvailable = Math.floor((data.version - Version) * 10);
CheckForUpdatesButton.innerHTML = '<b>' + NumberOfUpdatesAvailable + ' update(s) available</b>';
alert(NumberOfUpdatesAvailable + ' updates available');
}
})
.catch(error => {console.log(error)});
.catch((error) => {
console.log(error);
});
}
CheckForUpdatesButton.addEventListener('click', CheckForUpdates)
CheckForUpdatesButton.addEventListener('click', CheckForUpdates);
fetch(chrome.runtime.getURL('resources/currencies.json'))
.then(response => {
.then((response) => {
if (!response.ok) {
throw new Error('Network not ok')
throw new Error('Network not ok');
}
return response.json()
return response.json();
})
.then(data => {
const DateText = new Date(data.Date).toLocaleDateString("en-US", {day:"numeric",month:"long",year:"numeric"})
document.getElementById('IRLPriceWithCurrency-Date').innerText = DateText
.then((data) => {
const DateText = new Date(data.Date).toLocaleDateString('en-US', {day: 'numeric', month: 'long', year: 'numeric'});
document.getElementById('IRLPriceWithCurrency-Date').innerText = DateText;
})
.catch(error => {console.log(error)})
.catch((error) => {
console.log(error);
});
chrome.storage.local.get(['PolyPlus_OutOfDate', 'PolyPlus_LiveVersion', 'PolyPlus_ReleaseNotes', 'PolyPlus_SkipUpdate'], function (result) {
const OutOfDate = result.PolyPlus_OutOfDate || false
const SkipUpdate = result.PolyPlus_SkipUpdate || null
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version
const OutOfDate = result.PolyPlus_OutOfDate || false;
const SkipUpdate = result.PolyPlus_SkipUpdate || null;
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version;
if (OutOfDate === true && SkipUpdate !== LiveVersion) {
const Banner = document.createElement('div')
Banner.classList = 'alert position-sticky p-3'
Banner.style = 'top: 30px; box-shadow: 0 0 20px 2px #000; z-index: 2000; background: rgb(163 39 39);'
const Banner = document.createElement('div');
Banner.classList = 'alert position-sticky p-3';
Banner.style = 'top: 30px; box-shadow: 0 0 20px 2px #000; z-index: 2000; background: rgb(163 39 39);';
Banner.innerHTML = `
<b>New Update Available!</b>
<br>
@ -403,15 +429,15 @@ chrome.storage.local.get(['PolyPlus_OutOfDate', 'PolyPlus_LiveVersion', 'PolyPlu
<a href="${result.PolyPlus_ReleaseNotes}" class="btn btn-primary btn-sm w-25" target="_blank">Go to Release Notes</a>
<button id="skip-this-update" class="btn btn-warning btn-sm w-25">(Not Recommended) Skip this Update</button>
</div>
`
document.getElementById('page').insertBefore(Banner, document.getElementById('page').children[1])
`;
document.getElementById('page').insertBefore(Banner, document.getElementById('page').children[1]);
const SkipButton = document.getElementById('skip-this-update')
const SkipButton = document.getElementById('skip-this-update');
SkipButton.addEventListener('click', function () {
Banner.remove()
chrome.storage.local.set({'PolyPlus_SkipUpdate': result.PolyPlus_LiveVersion}, function(){
console.log('set skip update to live version: ', result.PolyPlus_LiveVersion)
})
Banner.remove();
chrome.storage.local.set({PolyPlus_SkipUpdate: result.PolyPlus_LiveVersion}, function () {
console.log('set skip update to live version: ', result.PolyPlus_LiveVersion);
});
});
}
})
});