rewrote settings and new features

- rewrote settings

- reorganized several settings as nested objects

- added avatars enabled sub-setting of collectibles hoarder list

- added default min copies

- new feature: "Timed-Item Owner Check"

- new feature: "Hide User Ads"
This commit is contained in:
Index 2024-05-27 17:01:25 -05:00
parent 40f09022fb
commit fc230ec3b8
20 changed files with 1023 additions and 369 deletions

View file

@ -1,4 +1,4 @@
const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID
const BodyColors = [
"#f8f8f8",
"#cdcdcd",
@ -174,6 +174,14 @@ if (new URLSearchParams(window.location.search).has('sandbox')) {
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')

View file

@ -9,13 +9,13 @@ var BestFriendsData
let Utilities;
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result) {
Settings = result.PolyPlus_Settings || {}
Settings = result.PolyPlus_Settings || Utilities.DefaultSettings
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
}
if (Settings.ShowFriendCount === true) {
if (Settings.HomeFriendCountOn === true) {
ShowFriendCount()
}
@ -183,7 +183,7 @@ async function IRLPrice() {
for (let item of TrendingItems.children[1].getElementsByClassName('d-flex')[0].children) {
const Price = item.getElementsByClassName('text-success')[0]
if (Price !== undefined) {
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrencyCurrency)
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
let Span = document.createElement('span')
Span.classList = 'text-muted polyplus-price-tag'

View file

@ -1,6 +1,6 @@
if (window.location.pathname.split('/')[3] === "inventory") {
const UserID = window.location.pathname.split('/')[2]
if (UserID === JSON.parse(window.localStorage.getItem('account_info')).ID) {
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')
@ -155,7 +155,7 @@ 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('account_info')).Bricks)
let BrickBalance = parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).Bricks)
query = query.toLowerCase();
let Results = Array.from(ItemGrid.children)
for (let i = 0; i < Results.length; i++) {

View file

@ -18,7 +18,7 @@ if (UserID) {
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
Settings = result.PolyPlus_Settings || {}
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
}
@ -118,8 +118,8 @@ if (UserID) {
async function IRLPrice() {
const NetWorthElement = document.getElementsByClassName('float-end text-success')[0];
const IRLResult = await Utilities.CalculateIRL(NetWorthElement.innerText, Settings.IRLPriceWithCurrencyCurrency)
NetWorthElement.innerText = NetWorthElement.innerText + " ($" + IRLResult.result + " " + IRLResult.display + ")"
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() {
@ -137,7 +137,7 @@ function BestFriends() {
} else {
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')'
}
if (UserID !== JSON.parse(window.localStorage.getItem('account_info')).ID && document.getElementById('add-friend-button').classList.contains('btn-success') === false) {
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);
});
@ -147,7 +147,7 @@ function BestFriends() {
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('account_info')).ID) { return }
if (UserID === JSON.parse(window.localStorage.getItem('p+account_info')).ID) { return }
btn.setAttribute('disabled', 'true')
chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result) {

View file

@ -45,7 +45,7 @@ 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.IRLPriceWithCurrencyCurrency || 0
Type.selectedIndex = result.PolyPlus_Settings.IRLPriceWithCurrency.Currency || 0
});
//let Package = document.getElementById('polyplus-brickconverter-package')

View file

@ -1,9 +1,13 @@
/*
Debug page for Development
Accessable at /my/settings/polyplus-debug
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
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#main-content .container').innerHTML = `
<style>
#main-content .container label {
@ -32,14 +36,14 @@ document.querySelector('#main-content .container').innerHTML = `
</div>
</div>
<hr>
Created by <a href="/users/2782" target="_blank">Index</a>
Created by <a href="/u/Index" target="_blank">Index</a>
<br><br>
Beta Testers:
<ul>
<li><a href="/users/24435" target="_blank">datastore</a></li>
<li><a href="/users/17064" target="_blank">Emir</a></li>
<li><a href="/users/9219" target="_blank">InsertSoda</a></li>
<li><a href="/users/26895" target="_blank">qwp</a></li>
<li><a href="/u/datastore" target="_blank">datastore</a></li>
<li><a href="/u/Emir" target="_blank">Emir</a></li>
<li><a href="/u/InsertSoda" target="_blank">InsertSoda</a></li>
<li><a href="/u/qwp" target="_blank">qwp</a></li>
</ul>
</div>
<div class="col">
@ -225,3 +229,5 @@ document.getElementById('delete-all-data').addEventListener('click', function(){
chrome.storage.sync.getBytesInUse(["PolyPlus_Settings", "PolyPlus_PinnedGames", "PolyPlus_BestFriends", "PolyPlus_ItemWishlist"], function(bytes){
document.getElementById('data-size').innerText = bytes.toLocaleString()
});
})
}

View file

@ -1,5 +1,5 @@
var Settings;
let Theme = null;
let Theme = ``;
(async () => {
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
@ -11,7 +11,7 @@ let Theme = null;
Settings = MergeObjects(RawSettings || Utilities.DefaultSettings, Utilities.DefaultSettings);
// If theme exists, create a style element to represent it
if (Settings.ThemeCreatorOn && Settings.ThemeCreatorOn === true) {
if (Settings.ThemeCreator.Enabled && Settings.ThemeCreator.Enabled === true) {
switch (Settings.ThemeCreator.BGImageSize) {
case 0:
Settings.ThemeCreator.BGImageSize = 'fit'
@ -111,43 +111,57 @@ let Theme = null;
}
`
}
});
if (Settings.HideUserAdsOn === true) {
if (Settings.HideUserAdsOn.Banners === true) {
Theme += `
div[style^="max-width: 728px;"]:has(.text-center a[href^="/ads/"]) {
display: none;
}
`
}
if (Settings.HideUserAdsOn.Rectangles === true) {
Theme += `
div[style^="max-width: 300px;"]:has(.text-center a[href^="/ads/"]) {
display: none;
}
`
}
}
if (Settings.HideNotifBadgesOn === true) {
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">`
});
document.addEventListener('DOMContentLoaded', async function() {
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
return
}
/*
// Check if Theme Exists, if so Load It
if (Settings.ThemeCreatorOn && Settings.ThemeCreatorOn === true) {
if (!(Settings.ThemeCreator.WebsiteLogo === null)) {
document.querySelector('.nav-sidebar img').setAttribute('src', Settings.ThemeCreator.WebsiteLogo)
}
}
if (Settings.ThemeCreatorOn && Settings.ThemeCreatorOn === true && Theme != null) {
document.body.prepend(Theme)
}
*/
// Define Data
const UserData = {
ID: document.querySelector('.text-reset.text-decoration-none[href^="/users/"]').getAttribute('href').split('/')[2],
Bricks: document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g,'')
}
window.localStorage.setItem('account_info', JSON.stringify(UserData))
Utilities.InjectResource('getUserDetails')
document.body.setAttribute('data-URL', window.location.pathname)
if (Settings.IRLPriceWithCurrencyOn === true) {
const IRLResult = await Utilities.CalculateIRL(UserData.Bricks, Settings.IRLPriceWithCurrencyCurrency)
const BrickBalanceCount = [document.querySelector('.text-success .brickBalanceCount'), document.querySelector('.text-success .brickBalanceCont')]
BrickBalanceCount.forEach(element => {element.innerHTML += ` (${IRLResult.icon}${IRLResult.result} ${IRLResult.display})`});
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)
// Desktop
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 += `<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) {
@ -162,6 +176,12 @@ let Theme = null;
}
}
/*
if (Settings.HideUserAdsOn === true) {
Array.from(document.querySelectorAll('.text-center:has(a[href^="/ads"])')).forEach(ad => {ad.remove()})
}
*/
if (Settings.HideNotifBadgesOn === true) {
document.getElementsByClassName('notif-nav notif-sidebar').forEach(element => {element.remove();});
}

View file

@ -6,7 +6,7 @@ let Utilities;
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
Settings = result.PolyPlus_Settings
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
(async () => {
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
@ -26,7 +26,7 @@ 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.IRLPriceWithCurrencyCurrency)
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
let Span = document.createElement('span')
Span.classList = 'text-muted polyplus-price-tag'
@ -40,7 +40,7 @@ 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 (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice(element)
}
}

View file

@ -30,7 +30,6 @@
Observer.observe(Comments, {attributes: false, childList: true, subtree: false})
const LoadCreatorTag = function(element) {
console.log(element)
let NameElement = element.querySelector('.text-reset[href^="/users/"]')
if (Type === 'guilds') {
NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]')

View file

@ -95,13 +95,13 @@ function RequestGameProfile() {
async function CopyOwnedPlace() {
console.log('ran function')
if (PlaceData === null) {
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID)
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + 2640)
PlaceData = await PlaceData.json()
}
if (PlaceData.creator.id !== parseInt(JSON.parse(window.localStorage.getItem('account_info')).ID)) {
if (PlaceData.creator.id !== parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).ID)) {
console.log('returned')
return
//return
}
const DIV = document.createElement('div')

View file

@ -1,5 +1,5 @@
const PlaceID = window.location.pathname.split('/')[2]
const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
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;
@ -65,7 +65,7 @@ const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [
}
}
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
IRLPrice()
}
@ -370,7 +370,7 @@ async function IRLPrice() {
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.IRLPriceWithCurrencyCurrency)
const IRLResult = await Utilities.CalculateIRL(Price.innerText, Settings.IRLPriceWithCurrency.Currency)
let Span = document.createElement('span')
Span.classList = 'text-muted polyplus-price-tag'

View file

@ -1,5 +1,6 @@
const ItemID = window.location.pathname.split('/')[2]
const ItemType = document.querySelector('.row .badge').innerHTML
console.log(ItemType)
var Settings;
var ItemWishlist;
@ -7,6 +8,7 @@ var PurchaseBtn;
var WishlistBtn;
var ItemOwned;
var InitialOwners;
var OwnerPagesFetched = 0;
var Utilities;
@ -23,7 +25,13 @@ var Utilities;
}
ItemOwned = (PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null)
if (Settings.IRLPriceWithCurrencyOn === true && ItemOwned === false) {
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')
}
if (Settings.IRLPriceWithCurrency.Enabled === true && ItemOwned === false) {
IRLPrice()
}
@ -45,8 +53,13 @@ var Utilities;
}
}
if ((Settings.HoardersListOn === true && document.getElementById('resellers') !== null)) {
HoardersList(2)
if (document.getElementById('resellers') !== null) {
if (Settings.HoardersList.Enabled === true) {
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()
}
})
})();
@ -87,7 +100,7 @@ async function IRLPrice() {
Span.classList = 'text-muted polyplus-own-tag'
Span.style.fontSize = '0.7rem'
Span.style.fontWeight = 'normal'
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrencyCurrency)
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency)
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
PurchaseBtn.appendChild(Span)
}
@ -158,7 +171,6 @@ function HandleItemWishlist() {
}
function TryOnItems() {
console.log(Utilities, Utilities.MeshTypes, Utilities.TextureTypes)
const Avatar = {
"useCharacter": true,
"items": [],
@ -175,21 +187,21 @@ function TryOnItems() {
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 IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
//const IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
const TryIFrame = document.createElement('iframe')
TryIFrame.style = 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px;'
const TryOnBtn = document.createElement('button')
TryOnBtn.classList = 'btn btn-outline-warning'
TryOnBtn.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.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.addEventListener('click', function (){
fetch("https://api.polytoria.com/v1/users/" + JSON.parse(window.localStorage.getItem('account_info')).ID + "/avatar")
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');
@ -233,7 +245,7 @@ function TryOnItems() {
return response.json();
})
.then(data => {
if (AssetType === 'tool') {
if (ItemType === 'tool') {
Avatar.tool = data.url
} else {
Avatar.items.push(data.url)
@ -303,10 +315,10 @@ function TryOnItems() {
ItemThumbnail.parentElement.appendChild(TryOnBtn)
TryOnModal.children[1].prepend(TryIFrame)
Utilities.InjectResource('registerTooltips')
//Utilities.InjectResource('registerTooltips')
}
async function HoardersList(min) {
async function HoardersList(min, avatars) {
let Page = 0
let Tabs = document.getElementById('store-tabs')
@ -342,7 +354,11 @@ async function HoardersList(min) {
})
})
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())
@ -350,8 +366,10 @@ async function HoardersList(min) {
Owners.push(...InitialOwners.inventories)
// Get owners (up to 300, if needed)
if (InitialOwners.pages > 1) {
if (InitialOwners.pages > 3) {InitialOwners.pages = 3}
if (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)
@ -374,7 +392,16 @@ async function HoardersList(min) {
}
}
let Hoarders = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies)
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)
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
// Break hoarders into groups of 4
@ -385,10 +412,15 @@ async function HoardersList(min) {
TabContent.innerHTML = `
<div id="p+hoarders-container">
${ 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) ? `
<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">
@ -412,7 +444,15 @@ async function HoardersList(min) {
</div>
</div>
`).join('')
}
: `
<div class="card mb-3">
<div class="card-body text-center py-5 text-muted">
<h1 class="display-3"><i class="fa-solid fa-rectangle-history-circle-user"></i></h1>
<h5> No hoarders </h5>
<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">
@ -422,7 +462,8 @@ async function HoardersList(min) {
<option value="3">Min. 3+ Copies</option>
<option value="5">Min. 5+ Copies</option>
<option value="10">Min. 10+ Copies</option>
<option value="10">Min. 15+ Copies</option>
<option value="15">Min. 15+ Copies</option>
<option value="35">Min. 35+ Copies</option>
</select>
</li>
<li class="page-item disabled">
@ -458,6 +499,7 @@ async function HoardersList(min) {
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}"]`))
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
@ -505,7 +547,6 @@ async function HoardersList(min) {
MinCopies.addEventListener('change', function(){
Page = 0
min = parseInt(MinCopies.options[MinCopies.selectedIndex].value)
console.log(min)
Hoarders = Object.values(Formatted).filter((x, index) => x.copies >= min).sort((a, b) => b.copies - a.copies)
AmountOfHoarders = Hoarders.length
Groups = []
@ -518,10 +559,17 @@ async function HoardersList(min) {
const UpdateHoardersList = function() {
console.log(Hoarders, AmountOfHoarders, Groups)
Current.innerText = Page+1
if (Groups[Page] !== undefined) {
Container.innerHTML = Groups[Page].map((x) => `
<div class="card mb-3">
<div class="card-body">
<div class="row">
${ (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">
@ -542,6 +590,19 @@ async function HoardersList(min) {
`).join('')
Utilities.InjectResource('registerTooltips')
} else {
Container.innerHTML = `
<div class="card mb-3">
<div class="card-body text-center py-5 text-muted">
<h1 class="display-3"><i class="fa-solid fa-rectangle-history-circle-user"></i></h1>
<h5> No hoarders </h5>
<p class="mb-0">This item is fresh and doesn't have any hoarders yet! Come back later!</p>
</div>
</div>
`
MinCopies.disabled = true
}
if (Page > 0) {
Prev.parentElement.classList.remove('disabled')
@ -560,3 +621,74 @@ async function HoardersList(min) {
}
})
}
function CheckOwner() {
const ImageCard = document.querySelector('.card-body:has(.store-thumbnail)')
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..">
<button class="btn btn-success">Check</button>
</div>
<b class="text-muted" style="font-size: 0.85rem;"><i class="fa-duotone fa-square-question mr-1"></i> ...</b>
`
ImageCard.appendChild(CheckOwnerDiv)
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>'
ImageCard.children[0].prepend(ToggleButton)
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')
} else {
CheckOwnerDiv.classList.add('d-none')
}
})
UsernameInput.addEventListener('update', function(){
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 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())
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 + '".'
} 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 + '".'
}
} else {
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,5 +1,5 @@
const ItemID = window.location.pathname.split('/')[2]
const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID
const ItemGrid = document.getElementById('assets')
const Categories = document.getElementById('store-categories').children[0]
@ -15,14 +15,17 @@ chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
Utilities = Utilities.default
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
Array.from(ItemGrid.children).forEach(element => {
LoadIRLPrices(element)
});
}
if (Settings.StoreOwnTagOn === true) {
Inventory = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?limit=50')).json()).inventory
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)
});
@ -51,7 +54,7 @@ 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 === 'mb-3 itemCardCont') {
if (Settings.IRLPriceWithCurrencyOn === true) {
if (Settings.IRLPriceWithCurrency.Enabled === true) {
LoadIRLPrices(element)
}
@ -74,7 +77,7 @@ async function LoadIRLPrices(element) {
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.IRLPriceWithCurrencyCurrency)
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency)
Span.innerText = "($" + IRLResult.result + " " + IRLResult.display + ")"
Parent.appendChild(Span)
}

View file

@ -17,7 +17,7 @@
{
"matches": ["https://polytoria.com/my/settings/*"],
"js": ["/js/settings.js"],
"js": ["/js/settings.js", "/js/debug.js"],
"run_at": "document_start"
},
@ -27,11 +27,6 @@
"run_at": "document_idle"
},
{
"matches": ["https://polytoria.com/my/settings/polyplus#dev"],
"js": ["/js/debug.js"]
},
{
"matches": ["https://polytoria.com/places/**"],
"js": ["/js/places/place-view.js"]
@ -78,7 +73,7 @@
},
{
"matches": ["https://polytoria.com/users/*/inventory/*"],
"matches": ["https://polytoria.com/u/*/inventory/"],
"js": ["/js/account/inventory.js"],
"run_at": "document_idle"
},
@ -104,7 +99,7 @@
},
{
"matches": ["https://polytoria.com/inbox/*", "https://polytoria.com/inbox?*"],
"matches": ["https://polytoria.com/inbox*"],
"js": ["/js/account/inbox.js"]
},

View file

@ -50,20 +50,24 @@
</div>
</div>
</div>
<div class="row">
<div class="row mb-3">
<div class="col">
<button id="myself" class="btn btn-outline-primary w-100 mb-3">
<button id="myself" class="btn btn-outline-primary w-100">
<i class="fa-duotone fa-shirt"></i>
Myself
</button>
</div>
<div class="col">
<button id="clear" class="btn btn-outline-warning w-100 mb-3">
<button id="clear" class="btn btn-outline-warning w-100">
<i class="fa-duotone fa-trash"></i>
Clear
</button>
</div>
</div>
<div class="input-group mb-3">
<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">
<h6 class="card-header">
<i class="fad fa-palette"></i>

View file

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

View file

@ -20,6 +20,11 @@ export default {
ForumMentsOn: true,
BestFriendsOn: false,
ImprovedFrListsOn: false,
IRLPriceWithCurrency: {
Enabled: true,
Currency: 0,
Package: 0
},
IRLPriceWithCurrencyOn: true,
IRLPriceWithCurrencyCurrency: 0,
IRLPriceWithCurrencyPackage: 0,
@ -27,6 +32,7 @@ export default {
StoreOwnTagOn: true,
ThemeCreatorOn: false,
ThemeCreator: {
Enabled: false,
BGColor: null,
BGImage: null,
BGImageSize: 'fit',
@ -38,7 +44,7 @@ export default {
ModifyNavOn: false,
ModifyNav: [
{
Label: "Play",
Label: "Places",
Link: "https://polytoria.com/places"
},
{
@ -59,6 +65,10 @@ export default {
}
],
MoreSearchFiltersOn: true,
ApplyMembershipTheme: {
Enabled: false,
Theme: 0
},
ApplyMembershipThemeOn: false,
ApplyMembershipThemeTheme: 0,
MultiCancelOutTradesOn: true,
@ -69,13 +79,25 @@ export default {
ShowPlaceRevenueOn: true,
ReplaceItemSalesOn: false,
HoardersListOn: true,
LibraryDownloadsOn: true
HoardersList: {
Enabled: true,
AvatarsEnabled: false,
MinCopies: 2
},
LibraryDownloadsOn: true,
EventItemsCatOn: true,
HomeFriendCountOn: true,
HideUserAds: {
Enabled: false,
Banners: true,
Rectangles: true
}
},
Limits: {
PinnedGames: 10,
BestFriends: 10,
ImprovedFrLists: 25,
ItemWishlist: 30
BestFriends: 15,
ImprovedFrLists: 20,
ItemWishlist: 20
},
MeshTypes: [
"hat",
@ -89,9 +111,9 @@ export default {
"tool"
],
TextureTypes: [
"Shirt",
"Pants",
"Face"
"shirt",
"pants",
"face"
],
CalculateIRL: async function(bricks, to, brickPackage) {
/*

View file

@ -19,7 +19,7 @@
#page {
margin-top: 7.5rem;
width: 50%;
width: 65%;
margin-right: auto;
margin-left: auto;
margin-bottom: 3.5rem;
@ -132,14 +132,14 @@
<label>Save Theme to JSON</label>
<div class="input-group mb-3">
<input id="SaveThemeToJSONInput" type="text" class="form-control bg-dark" placeholder="JSON String..." data-ignore="true" 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" placeholder="JSON..." data-ignore="true">
<button id="LoadThemeFromJSONBtn" class="btn btn-success" data-ignore="true" data-onclick="LoadThemeJSON(this.previousElementSibling.value)">Load</button>
<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">
@ -367,7 +367,7 @@
<span class="indicator">&nbsp;</span>
<span class="title">
Show IRL price with Brick Count
<button class="btn btn-sm toggle-btn" data-setting="IRLPriceWithCurrencyOn">Toggle</button>
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="IRLPriceWithCurrency">Toggle</button>
</span>
<br>
<span class="desc mb-4">
@ -377,7 +377,7 @@
<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="IRLPriceWithCurrencyCurrency">
<select id="IRLPriceWithCurrencyCurrency" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Currency" data-parent="IRLPriceWithCurrency">
<option value="USD" selected>United States Dollar (USD)</option>
<option value="EUR">Euro (EUR)</option>
<option value="CAD">Canadian Dollar (CAD)</option>
@ -388,7 +388,7 @@
<option value="BRL">Brazilian Real (BRL)</option>
</select>
<!--
<select id="IRLPriceWithCurrencyPackage" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="IRLPriceWithCurrencyPackage">
<select id="IRLPriceWithCurrencyPackage" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Package" data-parent="IRLPriceWithCurrency">
<option value="0" selected>$0.99 Brick Package</option>
<option value="1">$4.99 Brick Package</option>
<option value="2">$9.99 Brick Package</option>
@ -420,7 +420,7 @@
<span class="indicator">&nbsp;</span>
<span class="title">
Theme Creator
<button class="btn btn-sm toggle-btn" data-setting="ThemeCreatorOn">Toggle</button>
<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>
@ -441,11 +441,11 @@
<span class="indicator">&nbsp;</span>
<span class="title">
Apply Membership Theme for <b>Free</b>
<button class="btn btn-sm toggle-btn" data-setting="ApplyMembershipThemeOn">Toggle</button>
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ApplyMembershipTheme">Toggle</button>
</span>
<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="ApplyMembershipThemeTheme">
<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>
<option value="PlusDX">Plus Deluxe</option>
</select>
@ -543,12 +543,22 @@
</span>
<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">
<label class="form-check-label" for="hoarders-list-avatars">Show Avatar Icons (more requests, resulting in more ratelimiting potentially)</label>
<label class="form-check-label" for="hoarders-list-avatars">
Show Avatar Icons
<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>
-->
<select class="form-select form-select-sm mb-2" style="width:350px;" data-setting="MinCopies" data-parent="HoardersList" data-useValue="true">
<option value="2">Min. 2+ Copies</option>
<option value="3">Min. 3+ Copies</option>
<option value="5">Min. 5+ Copies</option>
<option value="10">Min. 10+ Copies</option>
<option value="15">Min. 15+ Copies</option>
<option value="35">Min. 35+ Copies</option>
</select>
</p>
<p class="setting-container" id="hoarders-list">
<span class="indicator">&nbsp;</span>
@ -577,6 +587,38 @@
<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">
<span class="indicator">&nbsp;</span>
<span class="title">
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>
</p>
<p class="setting-container" id="hide-user-ads">
<span class="indicator">&nbsp;</span>
<span class="title">
Hide User Ads
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HideUserAds">Toggle</button>
</span>
<br>
<span class="desc">Hide those annoying <s>out of context Discord message</s> user ads!</span>
<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>
</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>
</span>
</p>
<div class="card">
<div class="card-body">
<h3>EXPERIMENTAL SETTINGS</h3>
@ -642,9 +684,9 @@
|
<a id="check-for-updates"><b>Check for Updates</b></a>
<br>
made by Index with the help of several contributors <3
made by <a href="https://polytoria.com/u/Index" target="_blank">Index</a> with the help of several contributors <3
</p>
</div>
<script src="settings.js"></script>
<script src="settings2.js"></script>
</body>
</html>

View file

@ -54,11 +54,14 @@ 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)
//let Checkbox = element.getElementsByTagName('input') || []
//console.log(Checkbox)
if (Button) {
Button.addEventListener('click', function() {
ToggleSetting(Button.getAttribute('data-setting'), element)
/*
if (!(Button.getAttribute('data-parent'))) {
ToggleSetting(Button.getAttribute('data-setting'), element)
} else {
@ -74,18 +77,16 @@ Elements.forEach(element => {
console.log(Button.getAttribute('data-setting'), Parent, Settings[Parent])
ToggleSetting(Button.getAttribute('data-setting'), element, Parent)
}
*/
});
}
/*
Array.from(Checkbox).forEach(check => {
console.log('anotha one')
check.addEventListener('click', function(){
console.log('clicky')
if (!(check.getAttribute('data-parent'))) {
console.log('no dad?')
ToggleSetting(check.getAttribute('data-setting'), element)
} else {
console.log('dad came back with milk')
let Parent = check.getAttribute('data-parent')
if (!isNaN(parseInt(Parent))) {
Parent = parseInt(Parent)
@ -101,6 +102,7 @@ Elements.forEach(element => {
}
})
})
*/
if (Options) {
Options.addEventListener('click', function() {

417
settings2.js Normal file
View file

@ -0,0 +1,417 @@
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()
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() {
Save();
});
// Handle modal buttons for Reset Defaults modal
document.getElementById('ResetDefaults-Modal-Yes').addEventListener('click', function() {
Settings = Utilities.DefaultSettings
Save()
setTimeout(function () {
LoadCurrent();
document.getElementById('ResetDefaults-Modal').close();
}, 400)
});
document.getElementById('ResetDefaults-Modal-No').addEventListener('click', function() {
document.getElementById('ResetDefaults-Modal').close();
});
// 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."
}
}
// 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]
if (Button) {
Button.addEventListener('click', function() {
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)
}
})
}
if (Checkbox) {
Checkbox.addEventListener('change', function(){
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')
Options.addEventListener('click', function(){
Array.from(ModalButtons).filter((x) => !x.classList.contains('ignore')).forEach(button => {
button.addEventListener('click', function(){
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(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)
} 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()
Modal.close();
}
} else if (Setting === '[cancel]') {
// Cancel Changes Button
Modal.close();
} else {
// Default Toggle Button
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
} else {
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
}
});
Modal.showModal()
})
}
});
function LoadCurrent() {
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
Settings = MergeObjects(result.PolyPlus_Settings || Utilities.DefaultSettings, Utilities.DefaultSettings)
console.log("Current Settings: ", Settings)
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')
if (modalParent !== undefined) {
console.log(modalParent)
parent = modalParent
}
if (value === "bool") {
value = !GetSettingValue(element, modalParent)
}
if (parent !== null) {
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'))]
}
Parent[name] = value
} else {
Settings[name] = value
}
if (update !== false) {
UpdateElementState(document.querySelector(`.setting-container:has([data-setting="${name}"])${ (parent !== null) ? `:has([data-parent="${parent}"])` : '' }`), value)
}
if (SaveBtn.getAttribute('disabled')) {
SaveBtn.removeAttribute('disabled')
}
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')
if (modalParent !== undefined) {
parent = modalParent
}
let Status = name;
if (parent !== null) {
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]
} else {
Status = Object.values(Parent)[Object.keys(Parent).indexOf(name)]
}
/*
if (!isNaN(element.getAttribute('data-parent'))) {
Parent = Parent[parseInt(element.getAttribute('data-parent'))]
}
Status = Object.values(Parent)[Object.keys(Parent).indexOf(Status)]
*/
} else {
Status = Settings[Status]
}
console.log('Get Value Result', Status)
return Status
}
function UpdateElementState(element, status) {
console.log('Update Element State', element, status)
const Button = element.getElementsByClassName('toggle-btn')[0]
if (status === undefined) {
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')
} 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')
}
let SelectInput = element.getElementsByTagName('select')[0]
if (SelectInput) {
console.log('Select Found')
SelectInput.selectedIndex = GetSettingValue(SelectInput)
}
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)
})
}
}
function Save() {
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);
}
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn')
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput')
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn')
LoadThemeFromJSONBtn.addEventListener('click', function(){
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value)
});
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)
.then(() => {
alert('Successfully copied theme data to clipboard!')
})
.catch(() => {
alert('Failure to copy theme data to clipboard.')
});
}
});
function LoadThemeJSON(string) {
try {
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()
for (let i = 0; i < JSONTable.length; i++) {
if (JSONTable[i][0] !== "#") {
JSONTable[i] = ""
}
}
Settings.ThemeCreator = MergeObjects(JSONTable, Utilities.DefaultSettings.ThemeCreator)
Save();
console.log(JSONTable.length, JSONTable, 'applied')
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].click();
}
} else {
alert('JSON is not a theme!')
}
} catch (error) {
alert('JSON is invalid!')
}
}
// MergeObjects function was written by ChatGPT cause I was lazy and it was awhile ago
function MergeObjects(obj1, obj2) {
var mergedObj = {};
// Copy the values from obj1 to the mergedObj
for (var key in obj1) {
mergedObj[key] = obj1[key];
}
// Merge the values from obj2 into the mergedObj, favoring obj2 for non-existing keys in obj1
for (var key in obj2) {
if (!obj1.hasOwnProperty(key)) {
mergedObj[key] = obj2[key];
}
}
return mergedObj;
}
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')
} 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)});
}
CheckForUpdatesButton.addEventListener('click', CheckForUpdates)
fetch(chrome.runtime.getURL('resources/currencies.json'))
.then(response => {
if (!response.ok) {
throw new Error('Network not ok')
}
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
})
.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
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);'
Banner.innerHTML = `
<b>New Update Available!</b>
<br>
Your Poly+ installation is out of date! If you would like to get the latest and greatest features, improvements, and bug fixes click on one of the links below to dismiss this banner!
<br>
<div role="group" class="btn-group w-100 mt-2">
<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])
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)
})
});
}
})