Compare commits
275 commits
public-bet
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a01c1be3da | |||
| 6349957fa3 | |||
| 0e3be312a8 | |||
| 5fc1c37383 | |||
| bcce85e63d | |||
| 172d666575 | |||
| bb4d5c06e5 | |||
| 7ae424b60b | |||
| 591dbe1f01 | |||
| 001f92db85 | |||
| 12e3a38e8d | |||
| 849e2dde84 | |||
| 70808ced7c | |||
| 4a65a22f17 | |||
| 9b20404929 | |||
| d0799a127f | |||
| 11ac584246 | |||
| c8da41a558 | |||
| 5743cf2422 | |||
| afe9eaaf6f | |||
| 4013251a8e | |||
| fd55054ac6 | |||
| 29539ac59e | |||
| 8ef22bf1cc | |||
| 1776bc8f44 | |||
| b112777a86 | |||
| 3dbdec5521 | |||
| 083d4cc80a | |||
| eaf161e9f0 | |||
| ae060b6e93 | |||
| f6102eafcc | |||
| f94f43b626 | |||
| aa840db336 | |||
| 80be8b407d | |||
| 3419e646cd | |||
| b95cf5d9df | |||
| fbb69d63ff | |||
| 2795cb7489 | |||
| ad3fe90caf | |||
| 67b092700a | |||
| d6d9bed142 | |||
| a650381218 | |||
| 96d78860f8 | |||
| 9350038f5c | |||
| 416519dbec | |||
| 57e9c7a289 | |||
| 7825c45431 | |||
| 2950561606 | |||
| d01fed21fe | |||
| 492a895e13 | |||
| 9857fc24e0 | |||
| 6e1ca47be6 | |||
| 48975f06c5 | |||
| 66451aa9cc | |||
| 9eeb7761e4 | |||
| 484c396233 | |||
| 908637e72e | |||
| c6a3ce2c69 | |||
| 9c8a08cf78 | |||
| 254ee41c11 | |||
| 2975795971 | |||
| f0ac985c13 | |||
| ffcb35d15f | |||
| 0eca6b62c7 | |||
| 90dab88d0e | |||
| 1ea8dae60c | |||
| 8cd989af3d | |||
| 9f49fc848d | |||
| 80d223e4d1 | |||
| 2e4ade1c97 | |||
| 077e49db36 | |||
| 83e2f19fa2 | |||
| 662f4733af | |||
| 5eeef015e4 | |||
| 0774558d7d | |||
| 35fe13d6a2 | |||
| 792375158d | |||
| 4a3ad2eb5f | |||
| f5f324b323 | |||
| d0a2223e76 | |||
| d0839859b5 | |||
| 7ba43cc07b | |||
| c7df8cbea3 | |||
| 7a745a6232 | |||
| 254957bdc7 | |||
| a20b22d148 | |||
| b631cb59e9 | |||
| 74488c4d2b | |||
| 14d9faa484 | |||
| d86f928b6f | |||
| ec9c7f8671 | |||
| 3e5ae5b782 | |||
| 8a82f9cc95 | |||
| 406b3ff479 | |||
| d743aaf820 | |||
| f6eba67d6e | |||
| bc6840c3d7 | |||
| ba19dd2691 | |||
| 7d0ef89748 | |||
| 923ce838bd | |||
| 577b71ae7c | |||
| 5be5e22f40 | |||
| d1f329a0e1 | |||
| 84f06e3b80 | |||
| 177da6b8af | |||
| cde27b8006 | |||
| 870def2dc1 | |||
| e8ee269945 | |||
| 2d6e5bd947 | |||
| ca5eb0829d | |||
| 0689cc3a9a | |||
| fdbabf43b0 | |||
| db00c107b8 | |||
| 6d290f5648 | |||
| 099b1c2b21 | |||
| aed860159b | |||
| e6cffdd8e2 | |||
| 8e8cf7981a | |||
| 3b0f079a2f | |||
| 431ef7ee73 | |||
| 85b4683a66 | |||
| 3206c6bbcd | |||
| 26c63d3bf6 | |||
| eb644e8f1e | |||
| 8228697bf9 | |||
| 4fce8c95cc | |||
| 5294df3e1d | |||
| db99562391 | |||
| 339c81e7a5 | |||
| 183c49891d | |||
| 5167016103 | |||
| 7e8e8d4b84 | |||
| bebd685bcd | |||
| f724cd9f3c | |||
| c636ee9576 | |||
| 8c249ad624 | |||
| 14250d1add | |||
| f65d95bca2 | |||
| 05b2e54847 | |||
| a222585718 | |||
| 7c586e0984 | |||
| e439cc9702 | |||
| 7f8cb33f01 | |||
| cfc25fd09b | |||
| d3a038bc42 | |||
| 5c3ef39e37 | |||
| 2cc4894d43 | |||
| 2249044de7 | |||
| 7207f229d2 | |||
| 2cce628807 | |||
| bcc2d4db6f | |||
| 661fcd8ee6 | |||
| ac4ca43be6 | |||
| fe3901a5f5 | |||
| f11c21c2be | |||
| 7bc077a420 | |||
| 439978a5b5 | |||
| 0e5a3d75e3 | |||
| 69b2a1599b | |||
| ff3e9595f5 | |||
| 3158d4ef91 | |||
| 0df034c46c | |||
| 2afea6ffb6 | |||
| 57e4130ede | |||
| 0f7aea03b2 | |||
| f9e3e5b09f | |||
| 1fd36f5a6d | |||
| 27a8986272 | |||
| a71b0f26be | |||
| 68f635495f | |||
| f434803f46 | |||
| f7fd5bde11 | |||
| 97866f933c | |||
| 05a3031a83 | |||
| 02fbb5c8bd | |||
| c821f9bc33 | |||
| 7f35484287 | |||
| 50b45b6614 | |||
| 350e3ab92f | |||
| a57098b608 | |||
| 6d09433395 | |||
| 1e5e9fe69f | |||
| 26dddf0019 | |||
| 438717ec46 | |||
| 24cfd40504 | |||
| ee6893f906 | |||
| ce3ebc99bb | |||
| 37ad14a9be | |||
| 373ef1b156 | |||
| deeaba05b2 | |||
| 9457437ba6 | |||
| f3e33ea840 | |||
| c0dbbdeb0d | |||
| b3cfe05657 | |||
|
|
4b15275648 | ||
|
|
456bf389f0 | ||
| 35bc026724 | |||
| 6a42004dba | |||
|
|
4bc5cf2260 | ||
| 8258f2b892 | |||
| 4577213ee9 | |||
| beb002feb9 | |||
| 1a2af482aa | |||
| 4bf9139a60 | |||
| 120f8cc23e | |||
|
|
273d524fe0 | ||
|
|
fd940da48a | ||
| 28e483b02e | |||
|
|
0ff8fac37b | ||
|
|
e1ace9551b | ||
| d63760ec50 | |||
| 30ebcc854a | |||
| 63b55d9883 | |||
|
|
ff6c26cb0a | ||
| 121676bda8 | |||
|
|
cc39111694 | ||
|
|
d25b2f97c2 | ||
|
|
bf6e9048c0 | ||
|
|
70241eead6 | ||
| b21af09301 | |||
|
|
8f687c53b1 | ||
|
|
5a425667f2 | ||
| fc230ec3b8 | |||
|
|
28881e45a1 | ||
|
|
e5e5721085 | ||
| 40f09022fb | |||
| c1bee43f08 | |||
| 6ebc9cc596 | |||
| 55ad153d2b | |||
| 8b20599662 | |||
| eeaafeb35a | |||
| 9478b85f49 | |||
| b15c39f861 | |||
| 706467c98b | |||
| 04bac6431f | |||
| 4566b7d031 | |||
| f3077da95f | |||
| a8cf983e26 | |||
| 066babda56 | |||
| 5fea28c467 | |||
| 2e146391b1 | |||
| f4a8163745 | |||
| 251e28edeb | |||
| 79f6b3a237 | |||
|
|
7af0a628b0 | ||
| b87c899256 | |||
| 948c9b8fae | |||
| f35921c3d4 | |||
| 641cfbdb6e | |||
| 1ab547d84c | |||
| 877cd65c6d | |||
| 1bb9b7c1d7 | |||
| 1b93ed22ad | |||
| 7cd6fb578b | |||
| 803de88fa0 | |||
| 673f289fd3 | |||
| a334e4be1d | |||
|
|
489309814b | ||
|
|
dadaab5a5c | ||
|
|
5f260a620e | ||
| 2212529309 | |||
| 08732c7537 | |||
| 46efc889e7 | |||
|
|
b4a4f5e6fa | ||
|
|
5f601f8c07 | ||
|
|
b2469a80af | ||
| f0b07d2ddc | |||
| a39ae5ad31 | |||
| 87d6087fa5 | |||
|
|
b42af5ded1 | ||
|
|
346fb3c435 | ||
|
|
7a676e1d1a | ||
|
|
061ec729d7 | ||
| 93e6b4340c | |||
| 3d6b265de0 |
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.DS_Store
|
||||||
|
manifest.json
|
||||||
100
README.md
|
|
@ -1,13 +1,95 @@
|
||||||
> Public BETA Testing
|
> [!CAUTION]
|
||||||
|
> Poly+ is in no way affiliated with the Polytoria team. This is a project I started for the community - and I hope some community members are willing to help with development so the extension is better for everyone ❤️.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> This extension is currently in BETA. If you find any bugs, please report them in this repository's issues section as it'd be a great help towards the development of the extension.
|
||||||
|
|
||||||
# Poly+
|
# Poly+
|
||||||
Poly+ is an upcoming quality-of-life browser extension for the Polytoria website! The extension provides tons of improvements to improve your experience on Polytoria!
|
|
||||||
|
Poly+ is a quality-of-life browser extension for the Polytoria website! The extension provides tons of improvements to improve your experience on Polytoria! Visit the website [here](https://polyplus.vercel.app/)!
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
# Features
|
||||||
|
|
||||||
|
- 📍 Pinned Games
|
||||||
|
- 📣 Forum Mentions
|
||||||
|
- 🎨 Theme Creator
|
||||||
|
- 🆕 Store "owned" Tags
|
||||||
|
- 🧾 Item Wishlist
|
||||||
|
- Best Friends
|
||||||
|
- Improved Friend Lists
|
||||||
|
- IRL Price with Brick Count
|
||||||
|
- Hide Sidebar Notification Badges
|
||||||
|
- More Search Filters
|
||||||
|
- Modify Navbar
|
||||||
|
- Free Membership Themes
|
||||||
|
- Multi-Cancel Outbound Trades
|
||||||
|
- Quick Place Downloads
|
||||||
|
- Try-On Items
|
||||||
|
- Show Outfit Cost on Profiles
|
||||||
|
- Show Approximate Place Revenue
|
||||||
|
- Show "Owners" instead of "Sales"
|
||||||
|
- Collectibles' Hoarders List
|
||||||
|
- Quick Library Downloads
|
||||||
|
- "Event Items" Store Category
|
||||||
|
- Show Friend Count on Homepage
|
||||||
|
- Timed-Item Owner Check
|
||||||
|
- Hide User Ads
|
||||||
|
- Multi-Decal Uploading
|
||||||
|
- Avatar Dimension Toggle
|
||||||
|
|
||||||
|
And there is more to come!
|
||||||
|
|
||||||
|
### Experimental Settings
|
||||||
|
|
||||||
|
> Experimental settings may not be finished and may have bugs!
|
||||||
|
|
||||||
|
- Game Profiles
|
||||||
|
- Inline Editing
|
||||||
|
- Forum Unix Timestamps
|
||||||
|
- Avatar Sandbox
|
||||||
|
|
||||||
# Supported Browsers
|
# Supported Browsers
|
||||||
As of right now, Poly+ only works on chromium-based browsers and Firefox (however it has not been tested and is not going to be as maintained). Currently, there are no plans to bring it to other browsers in the future.
|
|
||||||
> TL;DR Chromium-based browsers
|
|
||||||
|
|
||||||
# How to Download?
|
Poly+ is supported on Chromium-based browsers and Firefox!
|
||||||
1. First enable developer mode on your browser (developer mode allows you to load unpacked extensions)
|
|
||||||
2. Second click the "Load Unpacked" button
|
## Examples of Browsers that are Chromium-based
|
||||||
3. Third when the file selector comes up pick the unzipped folder from this GitHub repository
|
|
||||||
4. Fourth go to Polytoria and you should see the extension's button on the sidebar
|
- Google Chrome
|
||||||
|
- Chromium
|
||||||
|
- Edge
|
||||||
|
- Opera (& it's variations)
|
||||||
|
- Brave
|
||||||
|
- Arc
|
||||||
|
|
||||||
|
# Downloading
|
||||||
|
|
||||||
|
## How to Download - Stable Build?
|
||||||
|
|
||||||
|
1. Go to the extensions (or add-ons) webstore for your respective browser:
|
||||||
|
- Chromium-based browsers: [Chrome Webstore](https://chromewebstore.google.com/detail/poly+/feafepokhecfmimpepbpccmcnjbcbklg)
|
||||||
|
- Firefox: [Firefox Add-ons Store](https://addons.mozilla.org/en-US/firefox/addon/polytoriaplus/)
|
||||||
|
|
||||||
|
2. Click on the Poly+ icon in your browser's tooltip (if it's pinned, if not you may have to go to a sub-menu in your browser's toolbar and find the extension there) to go to the settings page, and customize your experience. Remember to click save at the bottom of the page when you are done!
|
||||||
|
|
||||||
|
3. Go to Polytoria's website and enjoy the many features and QOL improvements that come with Poly+!
|
||||||
|
|
||||||
|
## How to Download - Pre-Release Build?
|
||||||
|
|
||||||
|
> Pre-release builds may have work-in-progress features or bugs!
|
||||||
|
|
||||||
|
1. Go to the top of this GitHub repository
|
||||||
|
2. Click on the "Code" button
|
||||||
|
3. Click on the "Download ZIP" button in the dropdown menu
|
||||||
|
4. Extract the .ZIP
|
||||||
|
5. Enable developer mode on your browser (developer mode allows you to load unpacked extensions)
|
||||||
|
6. Go to your browser extensions page (usually `browserName://extensions`)
|
||||||
|
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!
|
||||||
15664
css/polytoria.css
Normal file
|
|
@ -1,60 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: LexendRegular;
|
|
||||||
src: url('Lexend-Regular.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: LexendLight;
|
|
||||||
src: url('Lexend-Light.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: LexendBold;
|
|
||||||
src: url('Lexend-Bold.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: LexendBlack;
|
|
||||||
src: url('Lexend-Black.ttf');
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 12px;
|
|
||||||
font-family: LexendRegular;
|
|
||||||
background-color: #242424;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #424242;
|
|
||||||
width: 95%;
|
|
||||||
padding: 10px;
|
|
||||||
border: none;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #007bff;
|
|
||||||
width: 95%;
|
|
||||||
padding: 10px;
|
|
||||||
border: none;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,.h1 {
|
|
||||||
font-family: LexendBlack;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2,.h2 {
|
|
||||||
font-family: LexendBold;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
221
css/settings.css
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#page {
|
||||||
|
background: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url(/images/client-loading.png);
|
||||||
|
background-color: #222222;
|
||||||
|
background-size: 400px;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page {
|
||||||
|
margin-top: 7.5rem;
|
||||||
|
width: 65%;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 4.6rem;
|
||||||
|
/*color: rgb(48, 48, 48);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 span.indent {
|
||||||
|
border-left: 10px solid rgb(48, 48, 48);
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 span.highlight {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: rgb(48, 48, 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 span.indent {
|
||||||
|
border-left: 7.5px solid rgb(48, 48, 48);
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container:not(:last-child) {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .title {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .desc, .setting-container .warning, .setting-container .note {
|
||||||
|
display: block;
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .desc {
|
||||||
|
color: rgb(120, 120, 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-buttons {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-buttons button {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-buttons button:first-child:not(:last-child) {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container select:first-of-type {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goback {
|
||||||
|
color: rgb(120, 120, 120);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog {
|
||||||
|
background-color: #080808;
|
||||||
|
color: #c4c4c4;
|
||||||
|
border: 1px solid #3bafff;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
background-color: #000;
|
||||||
|
border-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-bottom: 2.75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog::backdrop {
|
||||||
|
background-color: rgba(0, 0, 0, 0.73);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog .modal-header p {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog .modal-body p:first-child {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .indicator {
|
||||||
|
border-radius: 5rem;
|
||||||
|
display: inline-block;
|
||||||
|
cursor: default;
|
||||||
|
margin-right: 4px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: text-top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container.enabled .indicator { background-color: #007bff;}
|
||||||
|
.setting-container.enabled .title { text-shadow: 0px 1px 3px blue; }
|
||||||
|
.setting-container.disabled .indicator { background-color: orangered; }
|
||||||
|
.setting-container.disabled .title { text-shadow: 0px 1px 3px orangered; }
|
||||||
|
|
||||||
|
.limited-time {
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
/*
|
||||||
|
changed the box shadow to black cause @dargy begged me to
|
||||||
|
box-shadow: -3px -3px 15px 0 rgba(255, 116, 16, 0.25) inset, 3px 3px 15px 0 rgba(205, 96, 255, 0.25) inset;
|
||||||
|
*/
|
||||||
|
box-shadow: -3px -3px 15px 0 black inset;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time .row {
|
||||||
|
--bs-gutter-x: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time .indicator {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time .desc {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time-tag {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: rgba(255, 116, 16, 0.25);
|
||||||
|
|
||||||
|
-webkit-animation: LimitedTimeTag 5s ease infinite alternate;
|
||||||
|
-moz-animation: LimitedTimeTag 5s ease infinite alternate;
|
||||||
|
animation: LimitedTimeTag 5s ease infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.limited-time::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
padding: 3px;
|
||||||
|
background:
|
||||||
|
linear-gradient(
|
||||||
|
45deg,
|
||||||
|
/*
|
||||||
|
changed the gradient to blue and green cause @ItsLuiggiYahoo begged me to
|
||||||
|
rgba(255, 116, 16, 1),
|
||||||
|
rgba(205, 96, 255, 1)
|
||||||
|
*/
|
||||||
|
blue,
|
||||||
|
green
|
||||||
|
);
|
||||||
|
mask:
|
||||||
|
linear-gradient(#fff 0 0) content-box,
|
||||||
|
linear-gradient(#fff 0 0);
|
||||||
|
-webkit-mask-composite: xor;
|
||||||
|
mask-composite: exclude;
|
||||||
|
display: block;
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .warning {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: orange;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-container .note {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #439eff;
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
--bs-card-border-color: #1e1e1e;
|
||||||
|
--bs-card-bg: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes LimitedTimeTag {
|
||||||
|
0%{color:rgba(255, 116, 16, 1);}
|
||||||
|
50%{color:rgba(23, 107, 233, 1);}
|
||||||
|
100%{color:rgba(205, 96, 255, 1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes LimitedTimeTag {
|
||||||
|
0%{color:rgba(255, 116, 16, 1);}
|
||||||
|
50%{color:rgba(23, 107, 233, 1);}
|
||||||
|
100%{color:rgba(205, 96, 255, 1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes LimitedTimeTag {
|
||||||
|
0%{color:rgba(255, 116, 16, 1);}
|
||||||
|
50%{color:rgba(23, 107, 233, 1);}
|
||||||
|
100%{color:rgba(205, 96, 255, 1);}
|
||||||
|
}
|
||||||
141
css/specific.css
|
|
@ -1,17 +1,140 @@
|
||||||
body[data-URL^="https://polytoria.com/my/friends"] .col-lg-3 {
|
/*
|
||||||
margin-bottom: 20px;
|
FRONTEND FIXES / SPACING IMPROVEMENTS
|
||||||
|
*/
|
||||||
|
|
||||||
|
body[data-URL^='/my/friends'] .col-lg-3 {
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-URL^="https://polytoria.com/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%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-URL^="https://polytoria.com/create/"] .col.d-flex.align-content-between.flex-wrap {
|
body[data-URL^='/create/'] .col.d-flex.align-content-between.flex-wrap {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-URL^='/create'] .me-2:has(.fa-thumbs-up)::after {
|
||||||
|
content: '%';
|
||||||
|
margin-left: -2.5px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-truncate {
|
.text-truncate {
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
text-overflow: ellipsis !important;
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#servers-tabpane .card {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-URL^='/my/settings/privacy'] .card-body:has([action^="/api/users/"]) .card {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-event-container .img-container {
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
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-hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.polyplus-inlineEditing-hidden {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
MODALS
|
||||||
|
*/
|
||||||
|
|
||||||
|
html:has(.polyplus-modal[open]),
|
||||||
|
body:has(.polyplus-modal[open]) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.polyplus-modal::backdrop {
|
||||||
|
background: rgba(0, 0, 0, 0.73);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
EVENT PLACE CARD HIGHLIGHT ANIMATION
|
||||||
|
CSS BY @Dragonism ON POLYTORIA
|
||||||
|
*/
|
||||||
|
|
||||||
|
.event-card {
|
||||||
|
background-size: 200% 200% !important;
|
||||||
|
|
||||||
|
-webkit-animation: EventPlace 5s ease infinite;
|
||||||
|
-moz-animation: EventPlace 5s ease infinite;
|
||||||
|
animation: EventPlace 5s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes EventPlace {
|
||||||
|
0%{background-position:10% 0%}
|
||||||
|
50%{background-position:91% 100%}
|
||||||
|
100%{background-position:10% 0%}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes EventPlace {
|
||||||
|
0%{background-position:10% 0%}
|
||||||
|
50%{background-position:91% 100%}
|
||||||
|
100%{background-position:10% 0%}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes EventPlace {
|
||||||
|
0%{background-position:10% 0%}
|
||||||
|
50%{background-position:91% 100%}
|
||||||
|
100%{background-position:10% 0%}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* - */
|
||||||
|
|
||||||
|
/*
|
||||||
|
AVATAR SANDBOX
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ribbon-polyplus-custom span {
|
||||||
|
background-color: orange !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon-polyplus-custom::after, .ribbon-polyplus-custom::before {
|
||||||
|
border-color: #c68000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon-polyplus-unknown span {
|
||||||
|
background-color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon-polyplus-unknown::after, .ribbon-polyplus-unknown::before {
|
||||||
|
border-color: #121212 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon-polyplus-retro span {
|
||||||
|
background-color: purple !important;
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ribbon-polyplus-retro::after, .ribbon-polyplus-retro::before {
|
||||||
|
border-color: rgb(104, 0, 104) !important;
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,23 @@
|
||||||
PolyPlus_Settings: []
|
Sync:
|
||||||
|
------------------
|
||||||
|
PolyPlus_Settings: {}
|
||||||
PolyPlus_PinnedGames: []
|
PolyPlus_PinnedGames: []
|
||||||
PolyPlus_BestFriends: []
|
|
||||||
PolyPlus_ItemWishlist: []
|
PolyPlus_ItemWishlist: []
|
||||||
|
PolyPlus_AvatarSandboxOutfits: []
|
||||||
|
PolyPlus_TimePlayed: {}
|
||||||
|
|
||||||
|
Local:
|
||||||
|
------------------
|
||||||
|
PolyPlus_InventoryCache: {
|
||||||
|
data: [],
|
||||||
|
requested: number (representing date)
|
||||||
|
}
|
||||||
|
PolyPlus_GreatDivideStats: {}
|
||||||
|
PolyPlus_FriendCount: {
|
||||||
|
count: number,
|
||||||
|
requested: number (representing date)
|
||||||
|
}
|
||||||
|
PolyPlus_AssetDesigners: {
|
||||||
|
data: {},
|
||||||
|
requested: number (representing date)
|
||||||
|
}
|
||||||
28
images/chrome-icon.svg
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
|
||||||
|
<title>chrome-color</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs>
|
||||||
|
|
||||||
|
</defs>
|
||||||
|
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="Color-" transform="translate(-400.000000, -1043.000000)">
|
||||||
|
<g id="chrome" transform="translate(400.000000, 1043.000000)">
|
||||||
|
<path d="M5.7954035,8.36130434 C16.9522782,-4.62351526 37.639151,-2.06037988 45.3727574,13.1072081 C39.9288251,13.1091897 31.4040328,13.1055761 26.786937,13.1072081 C23.4382318,13.1083738 21.2761308,13.0322537 18.9347285,14.2648621 C16.1820632,15.7138239 14.1051274,18.3997073 13.3801164,21.5544341 L5.7954035,8.36130434 L5.7954035,8.36130434 Z" id="chrome-icon-path" fill="#EA4335">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path d="M16.015461,23.9991346 C16.015461,28.3998753 19.5936811,31.9800817 23.9919804,31.9800817 C28.3901632,31.9800817 31.9683834,28.3998753 31.9683834,23.9991346 C31.9683834,19.5985104 28.3901632,16.0181875 23.9919804,16.0181875 C19.5936811,16.0181875 16.015461,19.5985104 16.015461,23.9991346 L16.015461,23.9991346 Z" id="chrome-icon-path" fill="#4285F4">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path d="M27.0876366,34.4456482 C22.6105798,35.7761751 17.371347,34.3006354 14.5014777,29.3468879 C12.3108329,25.5655987 6.52286114,15.4823164 3.89206021,10.8973955 C-5.32185953,25.0194695 2.61924235,44.2642006 19.3464574,47.5489026 L27.0876366,34.4456482 L27.0876366,34.4456482 Z" id="chrome-icon-path" fill="#34A853">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path d="M31.4014697,16.0181875 C35.1303309,19.4863704 35.9427207,25.102234 33.4168909,29.4566966 C31.5138971,32.7374352 25.4402549,42.9884614 22.4966379,47.9523505 C39.730883,49.0147671 52.2944399,32.1238121 46.6195946,16.0181875 L31.4014697,16.0181875 L31.4014697,16.0181875 Z" id="chrome-icon-path" fill="#FBBC05">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
BIN
images/client-loading.png
Normal file
|
After Width: | Height: | Size: 548 KiB |
107
images/firefox-icon.svg
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M28.9905 10.7265C28.3816 9.2574 27.1473 7.67139 26.1784 7.17039C26.967 8.72015 27.4232 10.2746 27.5976 11.4344C27.5976 11.4344 27.5976 11.4426 27.6005 11.4578C26.0156 7.49777 23.3277 5.90065 21.1327 2.42407C21.0213 2.24869 20.9105 2.07331 20.802 1.88566C20.7407 1.77985 20.6911 1.68397 20.648 1.59336C20.557 1.41757 20.4867 1.23179 20.4386 1.03975C20.439 1.03063 20.4359 1.02169 20.4301 1.01467C20.4243 1.00765 20.4161 1.00305 20.4071 1.00175C20.3985 0.999416 20.3894 0.999416 20.3808 1.00175C20.3785 1.00281 20.3763 1.00419 20.3744 1.00584C20.3709 1.00584 20.3674 1.00994 20.3639 1.0111L20.3697 1.0035C16.8483 3.07063 15.6536 6.89446 15.544 8.80784C14.1368 8.90428 12.7913 9.42358 11.683 10.298C11.5672 10.1998 11.4461 10.1081 11.3202 10.0232C11.0008 8.9027 10.9873 7.71683 11.2811 6.58931C9.84091 7.24697 8.72095 8.28463 7.90664 9.20303H7.90023C7.34433 8.49742 7.38341 6.17015 7.41491 5.68435C7.40849 5.65395 7.00076 5.89656 6.94826 5.93339C6.45773 6.2841 5.9992 6.67771 5.57805 7.1096C5.0988 7.59655 4.66096 8.12276 4.26909 8.68274C3.36752 9.96323 2.72814 11.4101 2.3879 12.9398C2.38149 12.9702 2.37565 13.0017 2.36924 13.0327C2.34299 13.1561 2.24791 13.7751 2.23099 13.9096V13.9406C2.10704 14.5803 2.02984 15.2282 2 15.8791V15.951C2 23.7097 8.27646 30 16.0182 30C22.9521 30 28.7088 24.9549 29.8364 18.328C29.8597 18.1485 29.8789 17.9673 29.8999 17.786C30.1788 15.3763 29.869 12.8439 28.9905 10.7265ZM12.8327 21.7239C12.8981 21.7549 12.9599 21.7894 13.027 21.8197L13.0363 21.8256C12.9692 21.7929 12.901 21.759 12.8333 21.7239H12.8327ZM27.6017 11.4642V11.4508V11.466V11.4642Z" fill="url(#paint0_linear_87_7118)"/>
|
||||||
|
<path d="M28.9907 10.7265C28.3818 9.25741 27.1475 7.67141 26.1786 7.17041C26.9672 8.72017 27.4234 10.2746 27.5978 11.4344V11.4631C28.9208 15.0572 28.1998 18.7121 27.1615 20.9452C25.555 24.4002 21.6661 27.9416 15.578 27.7692C9.00581 27.5821 3.21175 22.6885 2.1297 16.2842C1.93254 15.2735 2.1297 14.7608 2.22886 13.9406C2.10812 14.5725 2.06203 14.7555 2.00195 15.8791V15.951C2.00195 23.7098 8.27842 30 16.0202 30C22.954 30 28.7108 24.9549 29.8383 18.328C29.8616 18.1485 29.8809 17.9673 29.9019 17.7861C30.179 15.3764 29.8692 12.8439 28.9907 10.7265Z" fill="url(#paint1_radial_87_7118)"/>
|
||||||
|
<path d="M28.9907 10.7265C28.3818 9.25741 27.1475 7.67141 26.1786 7.17041C26.9672 8.72017 27.4234 10.2746 27.5978 11.4344V11.4631C28.9208 15.0572 28.1998 18.7121 27.1615 20.9452C25.555 24.4002 21.6661 27.9416 15.578 27.7692C9.00581 27.5821 3.21175 22.6885 2.1297 16.2842C1.93254 15.2735 2.1297 14.7608 2.22886 13.9406C2.10812 14.5725 2.06203 14.7555 2.00195 15.8791V15.951C2.00195 23.7098 8.27842 30 16.0202 30C22.954 30 28.7108 24.9549 29.8383 18.328C29.8616 18.1485 29.8809 17.9673 29.9019 17.7861C30.179 15.3764 29.8692 12.8439 28.9907 10.7265Z" fill="url(#paint2_radial_87_7118)"/>
|
||||||
|
<path d="M22.1776 12.3773C22.2085 12.3989 22.2359 12.4205 22.2651 12.4422C21.9133 11.8161 21.4749 11.243 20.9631 10.7398C16.6058 6.37292 19.821 1.27058 20.3629 1.01102L20.3687 1.00342C16.8473 3.07054 15.6526 6.89438 15.543 8.80776C15.7063 8.79665 15.869 8.78262 16.0353 8.78262C18.6631 8.78262 20.952 10.2312 22.1776 12.3773Z" fill="url(#paint3_radial_87_7118)"/>
|
||||||
|
<path d="M16.0446 13.2499C16.0219 13.6006 14.7899 14.8049 14.3589 14.8049C10.3725 14.8049 9.72559 17.2216 9.72559 17.2216C9.90058 19.2572 11.3157 20.9332 13.0277 21.82C13.1059 21.8604 13.1846 21.8966 13.2611 21.9329C13.3981 21.9913 13.5358 22.0498 13.6729 22.1018C14.26 22.3094 14.8748 22.4276 15.4969 22.4526C22.4838 22.7811 23.8383 14.08 18.7955 11.5534C20.0864 11.3283 21.4269 11.8492 22.1753 12.3759C20.9503 10.2299 18.6608 8.78125 16.033 8.78125C15.8667 8.78125 15.704 8.79528 15.5406 8.80639C14.1345 8.90403 12.7903 9.4239 11.6832 10.2983C11.8973 10.4801 12.1388 10.7221 12.6468 11.2237C13.6 12.1661 16.0394 13.1359 16.0446 13.2499Z" fill="url(#paint4_radial_87_7118)"/>
|
||||||
|
<path d="M16.0446 13.2499C16.0219 13.6006 14.7899 14.8049 14.3589 14.8049C10.3725 14.8049 9.72559 17.2216 9.72559 17.2216C9.90058 19.2572 11.3157 20.9332 13.0277 21.82C13.1059 21.8604 13.1846 21.8966 13.2611 21.9329C13.3981 21.9913 13.5358 22.0498 13.6729 22.1018C14.26 22.3094 14.8748 22.4276 15.4969 22.4526C22.4838 22.7811 23.8383 14.08 18.7955 11.5534C20.0864 11.3283 21.4269 11.8492 22.1753 12.3759C20.9503 10.2299 18.6608 8.78125 16.033 8.78125C15.8667 8.78125 15.704 8.79528 15.5406 8.80639C14.1345 8.90403 12.7903 9.4239 11.6832 10.2983C11.8973 10.4801 12.1388 10.7221 12.6468 11.2237C13.6 12.1661 16.0394 13.1359 16.0446 13.2499Z" fill="url(#paint5_radial_87_7118)"/>
|
||||||
|
<path d="M11.0311 9.83093C11.1448 9.90459 11.2382 9.96656 11.3227 10.0233C11.0034 8.90275 10.9899 7.71688 11.2837 6.58936C9.84345 7.24702 8.72349 8.28468 7.90918 9.20308C7.97509 9.20132 10.0085 9.16449 11.0311 9.83093Z" fill="url(#paint6_radial_87_7118)"/>
|
||||||
|
<path d="M2.1297 16.284C3.21175 22.6883 9.00581 27.5819 15.5827 27.769C21.6707 27.9414 25.5574 24.4 27.1661 20.945C28.2044 18.7113 28.9254 15.057 27.6025 11.4629V11.436C27.6025 11.4395 27.6025 11.4442 27.6054 11.4594C28.1024 14.7138 26.451 17.8665 23.8692 19.9986C23.8666 20.0045 23.8641 20.0106 23.8617 20.0167C18.8306 24.1223 14.0165 22.4936 13.0418 21.8289C12.9741 21.7962 12.9059 21.7623 12.8382 21.7272C9.9047 20.3242 8.69316 17.6438 8.95273 15.3469C6.47656 15.3469 5.63192 13.2529 5.63192 13.2529C5.63192 13.2529 7.85552 11.664 10.7861 13.046C13.5003 14.3262 16.0493 13.2535 16.0493 13.2529C16.0441 13.1389 13.6047 12.1662 12.6533 11.2267C12.1452 10.7251 11.9037 10.4831 11.6896 10.3013C11.5738 10.2031 11.4527 10.1114 11.3268 10.0265C11.2434 9.96809 11.1518 9.90963 11.0352 9.83421C10.0126 9.16778 7.97918 9.20461 7.9121 9.20636H7.90568C7.34978 8.50076 7.38886 6.17348 7.42036 5.68769C7.41395 5.65729 7.00621 5.89989 6.95371 5.93672C6.46318 6.28743 6.00465 6.68104 5.58351 7.11293C5.10426 7.59988 4.66642 8.12609 4.27455 8.68607C3.37298 9.96657 2.7336 11.4134 2.39336 12.9431C2.38228 12.97 1.88354 15.1523 2.1297 16.284Z" fill="url(#paint7_radial_87_7118)"/>
|
||||||
|
<path d="M20.9634 10.7399C21.4752 11.2431 21.9135 11.8162 22.2653 12.4423C22.3383 12.4971 22.4083 12.5557 22.4753 12.6176C25.6532 15.55 23.9908 19.7012 23.8642 19.9993C26.446 17.8673 28.0973 14.7146 27.6003 11.4601C26.0155 7.49777 23.3276 5.90065 21.1325 2.42407C21.0211 2.24869 20.9103 2.07331 20.8018 1.88566C20.7406 1.77985 20.691 1.68397 20.6478 1.59336C20.5569 1.41757 20.4866 1.23179 20.4384 1.03975C20.4388 1.03063 20.4358 1.02169 20.43 1.01467C20.4241 1.00765 20.4159 1.00305 20.4069 1.00175C20.3983 0.999416 20.3893 0.999416 20.3807 1.00175C20.3783 1.00281 20.3762 1.00419 20.3742 1.00584C20.3707 1.00584 20.3672 1.00994 20.3637 1.0111C19.8213 1.27066 16.606 6.37301 20.9634 10.7399Z" fill="url(#paint8_radial_87_7118)"/>
|
||||||
|
<path d="M22.4743 12.6146C22.4073 12.5526 22.3372 12.4941 22.2643 12.4392C22.2357 12.4176 22.206 12.396 22.1768 12.3743C21.4284 11.8482 20.088 11.3267 18.7971 11.5518C23.8393 14.0784 22.4854 22.7795 15.4985 22.451C14.8764 22.426 14.2616 22.3078 13.6744 22.1002C13.5374 22.0488 13.3997 21.9921 13.2626 21.9313C13.1833 21.895 13.1045 21.8588 13.0293 21.8185L13.0386 21.8243C14.0133 22.4908 18.8274 24.1194 23.8585 20.0121C23.8585 20.0121 23.8614 20.0045 23.8661 19.9939C23.9909 19.7011 25.6534 15.5499 22.4743 12.6146Z" fill="url(#paint9_radial_87_7118)"/>
|
||||||
|
<path d="M9.72532 17.2215C9.72532 17.2215 10.3722 14.8048 14.3586 14.8048C14.7897 14.8048 16.0216 13.5994 16.0444 13.2498C16.0671 12.9002 13.4953 14.3231 10.7811 13.0428C7.85055 11.6608 5.62695 13.2498 5.62695 13.2498C5.62695 13.2498 6.47159 15.3438 8.94776 15.3438C8.68819 17.6407 9.89973 20.3187 12.8332 21.7241C12.8986 21.755 12.9604 21.7895 13.0275 21.8199C11.3154 20.9349 9.90207 19.2571 9.72532 17.2215Z" fill="url(#paint10_radial_87_7118)"/>
|
||||||
|
<path d="M28.9905 10.7265C28.3816 9.2574 27.1473 7.67139 26.1784 7.17039C26.967 8.72015 27.4232 10.2746 27.5976 11.4344C27.5976 11.4344 27.5976 11.4426 27.6005 11.4578C26.0156 7.49777 23.3277 5.90065 21.1327 2.42407C21.0213 2.24869 20.9105 2.07331 20.802 1.88566C20.7407 1.77985 20.6911 1.68397 20.648 1.59336C20.557 1.41757 20.4867 1.23179 20.4386 1.03975C20.439 1.03063 20.4359 1.02169 20.4301 1.01467C20.4243 1.00765 20.4161 1.00305 20.4071 1.00175C20.3985 0.999416 20.3894 0.999416 20.3808 1.00175C20.3785 1.00281 20.3763 1.00419 20.3744 1.00584C20.3709 1.00584 20.3674 1.00994 20.3639 1.0111L20.3697 1.0035C16.8483 3.07063 15.6536 6.89446 15.544 8.80784C15.7073 8.79673 15.8701 8.78271 16.0363 8.78271C18.6641 8.78271 20.9531 10.2313 22.1786 12.3774C21.4302 11.8512 20.0898 11.3298 18.7989 11.5549C23.841 14.0815 22.4872 22.7826 15.5002 22.454C14.8782 22.429 14.2633 22.3108 13.6762 22.1033C13.5391 22.0518 13.4015 21.9951 13.2644 21.9343C13.1851 21.8981 13.1063 21.8618 13.0311 21.8215L13.0404 21.8273C12.9727 21.7946 12.9045 21.7607 12.8368 21.7256C12.9021 21.7566 12.964 21.7911 13.0311 21.8215C11.3155 20.9347 9.90216 19.2569 9.72542 17.2213C9.72542 17.2213 10.3723 14.8046 14.3587 14.8046C14.7898 14.8046 16.0217 13.5992 16.0445 13.2496C16.0392 13.1356 13.5998 12.1628 12.6484 11.2234C12.1403 10.7218 11.8988 10.4798 11.6848 10.298C11.5689 10.1998 11.4478 10.1081 11.3219 10.0232C11.0026 8.9027 10.9891 7.71683 11.2829 6.58931C9.84266 7.24697 8.7227 8.28463 7.90839 9.20303H7.90198C7.34608 8.49742 7.38516 6.17015 7.41666 5.68435C7.41024 5.65395 7.00251 5.89656 6.95001 5.93339C6.45948 6.2841 6.00095 6.67771 5.5798 7.1096C5.10055 7.59655 4.66271 8.12276 4.27084 8.68274C3.36927 9.96323 2.72989 11.4101 2.38965 12.9398C2.38324 12.9702 2.3774 13.0017 2.37099 13.0327C2.34474 13.1561 2.22574 13.7839 2.20941 13.9184C2.20941 13.9289 2.20941 13.9084 2.20941 13.9184C2.10019 14.5671 2.03026 15.2219 2 15.8791V15.951C2 23.7097 8.27646 30 16.0182 30C22.9521 30 28.7088 24.9549 29.8364 18.328C29.8597 18.1485 29.8789 17.9673 29.8999 17.786C30.1788 15.3763 29.869 12.8439 28.9905 10.7265ZM27.5999 11.4479V11.4631V11.4479Z" fill="url(#paint11_linear_87_7118)"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_87_7118" x1="27.135" y1="5.49261" x2="3.81392" y2="27.9437" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.05" stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.11" stop-color="#FFE847"/>
|
||||||
|
<stop offset="0.22" stop-color="#FFC830"/>
|
||||||
|
<stop offset="0.37" stop-color="#FF980E"/>
|
||||||
|
<stop offset="0.4" stop-color="#FF8B16"/>
|
||||||
|
<stop offset="0.46" stop-color="#FF672A"/>
|
||||||
|
<stop offset="0.53" stop-color="#FF3647"/>
|
||||||
|
<stop offset="0.7" stop-color="#E31587"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="paint1_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(26.0596 4.21879) scale(29.2246 29.2888)">
|
||||||
|
<stop offset="0.13" stop-color="#FFBD4F"/>
|
||||||
|
<stop offset="0.19" stop-color="#FFAC31"/>
|
||||||
|
<stop offset="0.25" stop-color="#FF9D17"/>
|
||||||
|
<stop offset="0.28" stop-color="#FF980E"/>
|
||||||
|
<stop offset="0.4" stop-color="#FF563B"/>
|
||||||
|
<stop offset="0.47" stop-color="#FF3750"/>
|
||||||
|
<stop offset="0.71" stop-color="#F5156C"/>
|
||||||
|
<stop offset="0.78" stop-color="#EB0878"/>
|
||||||
|
<stop offset="0.86" stop-color="#E50080"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint2_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(15.3809 16.1925) scale(29.2246 29.2888)">
|
||||||
|
<stop offset="0.3" stop-color="#960E18"/>
|
||||||
|
<stop offset="0.35" stop-color="#B11927" stop-opacity="0.74"/>
|
||||||
|
<stop offset="0.43" stop-color="#DB293D" stop-opacity="0.34"/>
|
||||||
|
<stop offset="0.5" stop-color="#F5334B" stop-opacity="0.09"/>
|
||||||
|
<stop offset="0.53" stop-color="#FF3750" stop-opacity="0"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint3_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(18.904 -2.42815) scale(21.172 21.2184)">
|
||||||
|
<stop offset="0.13" stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.25" stop-color="#FFDC3E"/>
|
||||||
|
<stop offset="0.51" stop-color="#FF9D12"/>
|
||||||
|
<stop offset="0.53" stop-color="#FF980E"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint4_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(12.1487 23.8433) scale(13.915 13.9455)">
|
||||||
|
<stop offset="0.35" stop-color="#3A8EE6"/>
|
||||||
|
<stop offset="0.47" stop-color="#5C79F0"/>
|
||||||
|
<stop offset="0.67" stop-color="#9059FF"/>
|
||||||
|
<stop offset="1" stop-color="#C139E6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint5_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(15.8005 12.7119) rotate(-13.9265) scale(7.37316 8.67852)">
|
||||||
|
<stop offset="0.21" stop-color="#9059FF" stop-opacity="0"/>
|
||||||
|
<stop offset="0.28" stop-color="#8C4FF3" stop-opacity="0.06"/>
|
||||||
|
<stop offset="0.75" stop-color="#7716A8" stop-opacity="0.45"/>
|
||||||
|
<stop offset="0.97" stop-color="#6E008B" stop-opacity="0.6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint6_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(15.011 3.02041) scale(10.0108 10.0328)">
|
||||||
|
<stop stop-color="#FFE226"/>
|
||||||
|
<stop offset="0.12" stop-color="#FFDB27"/>
|
||||||
|
<stop offset="0.3" stop-color="#FFC82A"/>
|
||||||
|
<stop offset="0.5" stop-color="#FFA930"/>
|
||||||
|
<stop offset="0.73" stop-color="#FF7E37"/>
|
||||||
|
<stop offset="0.79" stop-color="#FF7139"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint7_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(22.8805 -3.34313) scale(42.7109 42.8046)">
|
||||||
|
<stop offset="0.11" stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.46" stop-color="#FF980E"/>
|
||||||
|
<stop offset="0.62" stop-color="#FF5634"/>
|
||||||
|
<stop offset="0.72" stop-color="#FF3647"/>
|
||||||
|
<stop offset="0.9" stop-color="#E31587"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint8_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(18.7517 1.33374) rotate(84.2447) scale(31.1996 20.4543)">
|
||||||
|
<stop stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.06" stop-color="#FFE847"/>
|
||||||
|
<stop offset="0.17" stop-color="#FFC830"/>
|
||||||
|
<stop offset="0.3" stop-color="#FF980E"/>
|
||||||
|
<stop offset="0.36" stop-color="#FF8B16"/>
|
||||||
|
<stop offset="0.45" stop-color="#FF672A"/>
|
||||||
|
<stop offset="0.57" stop-color="#FF3647"/>
|
||||||
|
<stop offset="0.74" stop-color="#E31587"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint9_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(14.7757 6.73593) scale(26.6644 26.723)">
|
||||||
|
<stop offset="0.14" stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.48" stop-color="#FF980E"/>
|
||||||
|
<stop offset="0.59" stop-color="#FF5634"/>
|
||||||
|
<stop offset="0.66" stop-color="#FF3647"/>
|
||||||
|
<stop offset="0.9" stop-color="#E31587"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint10_radial_87_7118" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(21.8145 8.30059) scale(29.1844 29.2484)">
|
||||||
|
<stop offset="0.09" stop-color="#FFF44F"/>
|
||||||
|
<stop offset="0.23" stop-color="#FFE141"/>
|
||||||
|
<stop offset="0.51" stop-color="#FFAF1E"/>
|
||||||
|
<stop offset="0.63" stop-color="#FF980E"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint11_linear_87_7118" x1="26.855" y1="5.37218" x2="7.01043" y2="25.1739" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.17" stop-color="#FFF44F" stop-opacity="0.8"/>
|
||||||
|
<stop offset="0.27" stop-color="#FFF44F" stop-opacity="0.63"/>
|
||||||
|
<stop offset="0.49" stop-color="#FFF44F" stop-opacity="0.22"/>
|
||||||
|
<stop offset="0.6" stop-color="#FFF44F" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 15 KiB |
BIN
images/greatdivide.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
images/icon-update.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Poly+</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Thank you for installing Poly+!</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
1347
js/account/avatar-sandbox.js
Executable file → Normal file
|
|
@ -1,456 +0,0 @@
|
||||||
setTimeout(function () {}, 100)
|
|
||||||
const UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
|
|
||||||
|
|
||||||
let PageContainer = document.querySelector('.container.p-0.p-lg-5')
|
|
||||||
let ItemGrid;
|
|
||||||
let Wearing;
|
|
||||||
let Tabs;
|
|
||||||
let IFrame;
|
|
||||||
let TabSelected = 'hat'
|
|
||||||
let Search;
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
let ItemCardContents = `
|
|
||||||
<div style="max-width: 150px;">
|
|
||||||
<div class="card mb-2 avatar-item-container">
|
|
||||||
<div class="p-2">
|
|
||||||
<img src=":ItemThumbnail" class="img-fluid">
|
|
||||||
<span class="position-absolute" style="top: 5px; left: 5px; z-index: 1;">
|
|
||||||
<span class="badge bg-secondary">:ItemType</span>
|
|
||||||
</span>
|
|
||||||
<button class="avatarAction btn btn-success btn-sm position-absolute rounded-circle text-center" style="top: -10px; right: -16px; width: 32px; height: 32px; z-index: 1;"><i class="fas fa-plus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="/store/:ItemID" class="text-reset">
|
|
||||||
<h6 class="text-truncate mb-0"> :ItemName</h6>
|
|
||||||
</a>
|
|
||||||
<small class="text-muted d-block text-truncate">
|
|
||||||
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!')
|
|
||||||
|
|
||||||
LoadFile(chrome.runtime.getURL('js/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')
|
|
||||||
|
|
||||||
Search = document.getElementById('item-search')
|
|
||||||
Search.addEventListener('onchange', function(){
|
|
||||||
RefreshItems()
|
|
||||||
});
|
|
||||||
|
|
||||||
UpdateAvatar()
|
|
||||||
RefreshItems()
|
|
||||||
LoadWearing()
|
|
||||||
|
|
||||||
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 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()
|
|
||||||
});
|
|
||||||
|
|
||||||
let Myself = document.getElementById('myself')
|
|
||||||
Myself.addEventListener('click', function(){
|
|
||||||
LoadMyself()
|
|
||||||
});
|
|
||||||
|
|
||||||
let JSONUpload = document.getElementById('jsonUpload')
|
|
||||||
JSONUpload.addEventListener('change', function(){
|
|
||||||
let Reader = new FileReader()
|
|
||||||
Reader.addEventListener('loadend', function(){
|
|
||||||
Avatar = JSON.parse(Reader.result)
|
|
||||||
UpdateAvatar()
|
|
||||||
|
|
||||||
JSONUpload.value = ""
|
|
||||||
});
|
|
||||||
|
|
||||||
Reader.readAsText(JSONUpload.files[0])
|
|
||||||
});
|
|
||||||
|
|
||||||
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()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function UpdateAvatar() {
|
|
||||||
GenerateHash()
|
|
||||||
.then(hash => {
|
|
||||||
IFrame.addEventListener('load', function () {
|
|
||||||
IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + hash;
|
|
||||||
});
|
|
||||||
IFrame.src = 'about:blank';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadFile(path, callback) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
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)))
|
|
||||||
} else {
|
|
||||||
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 => {
|
|
||||||
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(':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)
|
|
||||||
});
|
|
||||||
|
|
||||||
ItemGrid.appendChild(NewItemCard)
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Fetch error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function FormatAvatar() {
|
|
||||||
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)
|
|
||||||
await FetchMesh(item)
|
|
||||||
.then(URL => {
|
|
||||||
console.log('URL: ' + URL)
|
|
||||||
FormattedAvatar.items[index] = URL
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
throw new Error(error)
|
|
||||||
});
|
|
||||||
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.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')
|
|
||||||
switch(info.type) {
|
|
||||||
case 'hat':
|
|
||||||
Avatar.items.push(info.id)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
Avatar[info.type] = info.id
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('unequip')
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = ''
|
|
||||||
}
|
|
||||||
let NewItemCard = document.createElement('div');
|
|
||||||
NewItemCard.classList = 'col-auto';
|
|
||||||
NewItemCard.innerHTML = ItemCardContents
|
|
||||||
.replace(':ItemName', item.name)
|
|
||||||
.replace(':ItemID', item.id)
|
|
||||||
.replace(':ItemType', item.type.charAt(0).toUpperCase() + item.type.substring(1))
|
|
||||||
.replace(':CreatorName', item.creator.name)
|
|
||||||
.replace(':CreatorID', item.creator.id)
|
|
||||||
.replace(':ItemThumbnail', item.thumbnail);
|
|
||||||
Wearing.appendChild(NewItemCard);
|
|
||||||
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
|
|
||||||
WearAsset(NewItemCard, item);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log('Fetch error: ' + error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Array.from(Wearing.children).length === 0) {
|
|
||||||
Wearing.innerHTML = 'No items to show.'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
function LoadWearing() {
|
|
||||||
const WearingItems = [
|
|
||||||
...Avatar.items,
|
|
||||||
Avatar.shirt,
|
|
||||||
Avatar.pants,
|
|
||||||
Avatar.face
|
|
||||||
].filter(item => item !== null)
|
|
||||||
|
|
||||||
Array.from(Wearing.children).forEach(element => {
|
|
||||||
console.log('AAAAAAAAAAAA', element)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
function LoadWearing() {
|
|
||||||
const AllItems = structuredClone(Avatar.items)
|
|
||||||
AllItems.push(Avatar.shirt)
|
|
||||||
AllItems.push(Avatar.pants)
|
|
||||||
AllItems.push(Avatar.face)
|
|
||||||
AllItems.forEach(item => {
|
|
||||||
if (item !== null) {
|
|
||||||
let Element = document.querySelector(`a[href="/store/${item}"]`)
|
|
||||||
if (Element !== null) {
|
|
||||||
console.log('exists - load wearing')
|
|
||||||
Element = Element.parentElement.parentElement
|
|
||||||
Wearing.appendChild(Element)
|
|
||||||
} else if (Element === null) {
|
|
||||||
console.log('doesn\' exist - load wearing')
|
|
||||||
fetch('https://api.polytoria.com/v1/store/:id'.replace(':id', item))
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok')
|
|
||||||
}
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then(item => {
|
|
||||||
let NewItemCard = document.createElement('div')
|
|
||||||
NewItemCard.classList = 'col-auto'
|
|
||||||
NewItemCard.innerHTML = ItemCardContents
|
|
||||||
.replace(':ItemName', item.name)
|
|
||||||
.replace(':ItemID', item.id)
|
|
||||||
.replace(':ItemType', item.type.charAt(0).toUpperCase() + item.type.substring(1))
|
|
||||||
.replace(':CreatorName', item.creator.name)
|
|
||||||
.replace(':CreatorID', item.creator.id)
|
|
||||||
.replace(':ItemThumbnail', item.thumbnail)
|
|
||||||
Wearing.appendChild(NewItemCard)
|
|
||||||
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function(){
|
|
||||||
WearAsset(NewItemCard, item)
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log('Fetch error: ' + error)
|
|
||||||
});
|
|
||||||
} else if (item.type === TabSelected) {
|
|
||||||
console.log('item type is selected tab - load wearing')
|
|
||||||
ItemGrid.appendChild(Element)
|
|
||||||
} else {
|
|
||||||
console.log('remove item - load wearing')
|
|
||||||
Element.remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
@ -1,212 +1,210 @@
|
||||||
var SelectedFriends = []
|
var SelectedFriends = [];
|
||||||
|
|
||||||
setTimeout(function () {
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
Settings = result.PolyPlus_Settings;
|
||||||
Settings = result.PolyPlus_Settings;
|
if (Settings.ImprovedFrListsOn === true) {
|
||||||
if (Settings.ImprovedFrListsOn === true) {
|
var Tab = 'requests';
|
||||||
var Tab = "requests"
|
|
||||||
|
|
||||||
var FriendsContainer = document.getElementById('friends-container')
|
var FriendsContainer = document.getElementById('friends-container');
|
||||||
var Container = document.createElement('div')
|
var Container = document.createElement('div');
|
||||||
Container.classList = 'row mb-3'
|
Container.classList = 'row mb-3';
|
||||||
Container.innerHTML = `
|
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="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>
|
<div class="col"><button id="DelAllFrBtn" class="btn btn-danger w-100">Decline all Friend Request(s)</button></div>
|
||||||
`
|
`;
|
||||||
FriendsContainer.parentElement.insertBefore(Container, FriendsContainer)
|
FriendsContainer.parentElement.insertBefore(Container, FriendsContainer);
|
||||||
var AccAllFrBtn = document.getElementById('AccAllFrBtn')
|
var AccAllFrBtn = document.getElementById('AccAllFrBtn');
|
||||||
var DelAllFrBtn = document.getElementById('DelAllFrBtn')
|
var DelAllFrBtn = document.getElementById('DelAllFrBtn');
|
||||||
var AccBtns = document.querySelectorAll('[onclick="acceptFriendRequest(this)"]')
|
var AccBtns = document.querySelectorAll('[onclick="acceptFriendRequest(this)"]');
|
||||||
var DelBtns = document.querySelectorAll('[onclick="declineFriendRequest(this)"]')
|
var DelBtns = document.querySelectorAll('[onclick="declineFriendRequest(this)"]');
|
||||||
if (!(AccBtns.length === 0)) {
|
if (!(AccBtns.length === 0)) {
|
||||||
AccAllFrBtn.addEventListener('click', function(){
|
AccAllFrBtn.addEventListener('click', function () {
|
||||||
AccBtns.forEach(element => {
|
AccBtns.forEach((element) => {
|
||||||
setTimeout(function () {}, 145)
|
setTimeout(function () {}, 145);
|
||||||
fetch('https://polytoria.com/api/friends/send', {
|
fetch('https://polytoria.com/api/friends/send', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }),
|
body: JSON.stringify({userID: parseInt(element.getAttribute('data-user-id'))})
|
||||||
})
|
}).catch((error) => {
|
||||||
.catch(error => {
|
// Handle any errors
|
||||||
// Handle any errors
|
console.error('Error:', error);
|
||||||
console.error('Error:', error);
|
Success = false;
|
||||||
Success = false
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let NewAcceptBtn = document.createElement('a')
|
let NewAcceptBtn = document.createElement('a')
|
||||||
NewAcceptBtn.style.display = 'none'
|
NewAcceptBtn.style.display = 'none'
|
||||||
sNewAcceptBtn.classList = 'btn btn-success'
|
sNewAcceptBtn.classList = 'btn btn-success'
|
||||||
NewAcceptBtn.setAttribute('data-user-id', element.getAttribute('data-user-id'))
|
NewAcceptBtn.setAttribute('data-user-id', element.getAttribute('data-user-id'))
|
||||||
NewAcceptBtn.setAttribute('onclick', 'acceptFriendRequest(this)')
|
NewAcceptBtn.setAttribute('onclick', 'acceptFriendRequest(this)')
|
||||||
FriendsContainer.appendChild(NewAcceptBtn)
|
FriendsContainer.appendChild(NewAcceptBtn)
|
||||||
NewAcceptBtn.click();
|
NewAcceptBtn.click();
|
||||||
*/
|
*/
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
AccAllFrBtn.setAttribute('disabled', 'true')
|
AccAllFrBtn.setAttribute('disabled', 'true');
|
||||||
}
|
}
|
||||||
if (!(DelBtns.length === 0)) {
|
if (!(DelBtns.length === 0)) {
|
||||||
DelAllFrBtn.addEventListener('click', function(){
|
DelAllFrBtn.addEventListener('click', function () {
|
||||||
DelBtns.forEach(element => {
|
DelBtns.forEach((element) => {
|
||||||
setTimeout(function () {}, 110)
|
setTimeout(function () {}, 110);
|
||||||
fetch('https://polytoria.com/api/friends/remove', {
|
fetch('https://polytoria.com/api/friends/remove', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ userID: parseInt(element.getAttribute('data-user-id')) }),
|
body: JSON.stringify({userID: parseInt(element.getAttribute('data-user-id'))})
|
||||||
})
|
}).catch((error) => {
|
||||||
.catch(error => {
|
// Handle any errors
|
||||||
// Handle any errors
|
console.error('Error:', error, document.querySelector('input[name="_csrf"]').value);
|
||||||
console.error('Error:', error, document.querySelector('input[name="_csrf"]').value);
|
Success = false;
|
||||||
Success = false
|
});
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let NewDeclineBtn = document.createElement('a')
|
let NewDeclineBtn = document.createElement('a')
|
||||||
NewDeclineBtn.style.display = 'none'
|
NewDeclineBtn.style.display = 'none'
|
||||||
NewDeclineBtn.classList = 'btn btn-danger'
|
NewDeclineBtn.classList = 'btn btn-danger'
|
||||||
NewDeclineBtn.setAttribute('data-user-id', element.getAttribute('data-user-id'))
|
NewDeclineBtn.setAttribute('data-user-id', element.getAttribute('data-user-id'))
|
||||||
NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)')
|
NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)')
|
||||||
FriendsContainer.appendChild(NewDeclineBtn)
|
FriendsContainer.appendChild(NewDeclineBtn)
|
||||||
NewDeclineBtn.click();
|
NewDeclineBtn.click();
|
||||||
*/
|
*/
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
DelAllFrBtn.setAttribute('disabled', 'true')
|
DelAllFrBtn.setAttribute('disabled', 'true');
|
||||||
}
|
}
|
||||||
let Text = document.createElement('p')
|
let Text = document.createElement('p');
|
||||||
Text.classList = 'mx-auto'
|
Text.classList = 'mx-auto';
|
||||||
Text.style.textAlign = 'center'
|
Text.style.textAlign = 'center';
|
||||||
Text.style.fontSize = '1.3rem'
|
Text.style.fontSize = '1.3rem';
|
||||||
Text.style.display = 'none'
|
Text.style.display = 'none';
|
||||||
Text.innerHTML = `
|
Text.innerHTML = `
|
||||||
<span>0</span> friends selected!
|
<span>0</span> friends selected!
|
||||||
<br>
|
<br>
|
||||||
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
|
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
|
||||||
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
|
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
|
||||||
<button id="removeSelectionBtn" class="btn btn-danger">Remove Selected Friends</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_Span = Text.querySelector('span');
|
||||||
let Text_View = document.getElementById('viewSelectionBtn');
|
let Text_View = document.getElementById('viewSelectionBtn');
|
||||||
let Text_Clear = document.getElementById('clearSelectionBtn');
|
let Text_Clear = document.getElementById('clearSelectionBtn');
|
||||||
let Text_Remove = document.getElementById('removeSelectionBtn');
|
let Text_Remove = document.getElementById('removeSelectionBtn');
|
||||||
document.querySelector('[data-friends-tab="requests"]').addEventListener('click', function(){
|
document.querySelector('[data-friends-tab="requests"]').addEventListener('click', function () {
|
||||||
Tab = "requests"
|
Tab = 'requests';
|
||||||
Container.style.display = '';
|
Container.style.display = '';
|
||||||
Text.style.display = 'none';
|
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"
|
});
|
||||||
Container.style.display = 'none';
|
document.querySelector('[data-friends-tab="friends"]').addEventListener('click', function () {
|
||||||
Text.style.display = '';
|
Tab = 'friends';
|
||||||
});
|
Container.style.display = 'none';
|
||||||
var ConfirmRemove = 0
|
Text.style.display = '';
|
||||||
Text_View.addEventListener('click', function(){});
|
});
|
||||||
Text_Clear.addEventListener('click', function(){
|
var ConfirmRemove = 0;
|
||||||
SelectedFriends = []
|
Text_View.addEventListener('click', function () {});
|
||||||
UpdateCheckboxes();
|
Text_Clear.addEventListener('click', function () {
|
||||||
Text_Span.innerText = SelectedFriends.length
|
SelectedFriends = [];
|
||||||
});
|
UpdateCheckboxes();
|
||||||
Text_Remove.addEventListener('click', function(){
|
Text_Span.innerText = SelectedFriends.length;
|
||||||
ConfirmRemove = ConfirmRemove + 1
|
});
|
||||||
switch(ConfirmRemove) {
|
Text_Remove.addEventListener('click', function () {
|
||||||
case 0:
|
ConfirmRemove = ConfirmRemove + 1;
|
||||||
Text_Remove.innerText = 'Remove Selected Friends'
|
switch (ConfirmRemove) {
|
||||||
break
|
case 0:
|
||||||
case 1:
|
Text_Remove.innerText = 'Remove Selected Friends';
|
||||||
Text_Remove.innerText = 'Are you sure?'
|
break;
|
||||||
break
|
case 1:
|
||||||
case 2:
|
Text_Remove.innerText = 'Are you sure?';
|
||||||
for (let i = 0; i < SelectedFriends.length; i++) {
|
break;
|
||||||
setTimeout(function () {}, 110)
|
case 2:
|
||||||
let NewDeclineBtn = document.createElement('a')
|
for (let i = 0; i < SelectedFriends.length; i++) {
|
||||||
NewDeclineBtn.style.display = 'none'
|
setTimeout(function () {}, 110);
|
||||||
NewDeclineBtn.classList = 'btn btn-danger'
|
let NewDeclineBtn = document.createElement('a');
|
||||||
NewDeclineBtn.setAttribute('data-user-id', SelectedFriends[i])
|
NewDeclineBtn.style.display = 'none';
|
||||||
NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)')
|
NewDeclineBtn.classList = 'btn btn-danger';
|
||||||
FriendsContainer.appendChild(NewDeclineBtn)
|
NewDeclineBtn.setAttribute('data-user-id', SelectedFriends[i]);
|
||||||
NewDeclineBtn.click();
|
NewDeclineBtn.setAttribute('onclick', 'declineFriendRequest(this)');
|
||||||
}
|
FriendsContainer.appendChild(NewDeclineBtn);
|
||||||
SelectedFriends = []
|
NewDeclineBtn.click();
|
||||||
UpdateCheckboxes();
|
}
|
||||||
Text_Remove.innerText = 'Remove Selected Friends'
|
SelectedFriends = [];
|
||||||
ConfirmRemove = 0
|
UpdateCheckboxes();
|
||||||
break
|
Text_Remove.innerText = 'Remove Selected Friends';
|
||||||
}
|
ConfirmRemove = 0;
|
||||||
});
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const observer = new MutationObserver(function (){
|
const observer = new MutationObserver(function () {
|
||||||
if (FriendsContainer.children.length > 0 && Tab === "friends") {
|
if (FriendsContainer.children.length > 0 && Tab === 'friends') {
|
||||||
LoadCheckBoxes();
|
LoadCheckBoxes();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
observer.observe(FriendsContainer, {childList: true, subtree: false});
|
observer.observe(FriendsContainer, {childList: true, subtree: false});
|
||||||
|
|
||||||
function LoadCheckBoxes() {
|
function LoadCheckBoxes() {
|
||||||
Array.from(FriendsContainer.children).forEach(element => {
|
Array.from(FriendsContainer.children).forEach((element) => {
|
||||||
let DeclineBtn = element.querySelector('a.btn.btn-danger')
|
let DeclineBtn = element.querySelector('a.btn.btn-danger');
|
||||||
let UserID = DeclineBtn.getAttribute('data-user-id')
|
let UserID = DeclineBtn.getAttribute('data-user-id');
|
||||||
let Column = document.createElement('div')
|
let Column = document.createElement('div');
|
||||||
let EditColumn = element.querySelector('.col-9')
|
let EditColumn = element.querySelector('.col-9');
|
||||||
Column.classList = 'col-auto'
|
Column.classList = 'col-auto';
|
||||||
var NewCheckBox = document.createElement('button')
|
var NewCheckBox = document.createElement('button');
|
||||||
NewCheckBox.classList = 'polyplus-multiremovefr-checkbox'
|
NewCheckBox.classList = 'polyplus-multiremovefr-checkbox';
|
||||||
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem;')
|
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem;');
|
||||||
var Index = SelectedFriends.indexOf(UserID)
|
var Index = SelectedFriends.indexOf(UserID);
|
||||||
if (Index !== -1) {
|
if (Index !== -1) {
|
||||||
DeclineBtn.classList.add('disabled')
|
DeclineBtn.classList.add('disabled');
|
||||||
NewCheckBox.style.borderColor = 'lime'
|
NewCheckBox.style.borderColor = 'lime';
|
||||||
}
|
}
|
||||||
EditColumn.classList.remove('col-9')
|
EditColumn.classList.remove('col-9');
|
||||||
EditColumn.classList.add('col')
|
EditColumn.classList.add('col');
|
||||||
Column.appendChild(NewCheckBox)
|
Column.appendChild(NewCheckBox);
|
||||||
EditColumn.parentElement.appendChild(Column)
|
EditColumn.parentElement.appendChild(Column);
|
||||||
NewCheckBox.addEventListener('click', function(){
|
NewCheckBox.addEventListener('click', function () {
|
||||||
var Index = SelectedFriends.indexOf(UserID)
|
var Index = SelectedFriends.indexOf(UserID);
|
||||||
if (Index === -1) {
|
if (Index === -1) {
|
||||||
DeclineBtn.classList.add('disabled')
|
DeclineBtn.classList.add('disabled');
|
||||||
SelectedFriends.push(UserID)
|
SelectedFriends.push(UserID);
|
||||||
NewCheckBox.style.borderColor = 'lime'
|
NewCheckBox.style.borderColor = 'lime';
|
||||||
} else {
|
} else {
|
||||||
SelectedFriends.splice(Index, 1)
|
SelectedFriends.splice(Index, 1);
|
||||||
NewCheckBox.style.borderColor = '#393939'
|
NewCheckBox.style.borderColor = '#393939';
|
||||||
DeclineBtn.classList.remove('disabled')
|
DeclineBtn.classList.remove('disabled');
|
||||||
}
|
}
|
||||||
Text_Span.innerText = SelectedFriends.length
|
Text_Span.innerText = SelectedFriends.length;
|
||||||
UpdateCheckboxes();
|
UpdateCheckboxes();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function UpdateCheckboxes(){
|
function UpdateCheckboxes() {
|
||||||
document.querySelectorAll('.polyplus-multiremovefr-checkbox').forEach(element => {
|
document.querySelectorAll('.polyplus-multiremovefr-checkbox').forEach((element) => {
|
||||||
let Parent = element.parentElement.parentElement.parentElement.parentElement.parentElement
|
let Parent = element.parentElement.parentElement.parentElement.parentElement.parentElement;
|
||||||
let DeclineBtn = Parent.querySelector('a.btn.btn-danger')
|
let DeclineBtn = Parent.querySelector('a.btn.btn-danger');
|
||||||
if (element.getAttribute('disabled')) {
|
if (element.getAttribute('disabled')) {
|
||||||
element.removeAttribute('disabled')
|
element.removeAttribute('disabled');
|
||||||
}
|
}
|
||||||
if (SelectedFriends.IndexOf(DeclineBtn.getAttribute('data-user-id')) === -1) {
|
if (SelectedFriends.IndexOf(DeclineBtn.getAttribute('data-user-id')) === -1) {
|
||||||
element.style.borderColor = '#393939'
|
element.style.borderColor = '#393939';
|
||||||
DeclineBtn.classList.remove('disabled')
|
DeclineBtn.classList.remove('disabled');
|
||||||
if (SelectedFriends.length >= 25) {
|
if (SelectedFriends.length >= 25) {
|
||||||
element.setAttribute('disabled', true)
|
element.setAttribute('disabled', true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DeclineBtn.classList.add('disabled')
|
DeclineBtn.classList.add('disabled');
|
||||||
element.style.borderColor = 'lime'
|
element.style.borderColor = 'lime';
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 100);
|
|
||||||
|
|
|
||||||
304
js/account/home.js
Executable file → Normal file
|
|
@ -1,147 +1,179 @@
|
||||||
var Settings;
|
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames'], async function(result){
|
||||||
var PinnedGames;
|
Settings = result.PolyPlus_Settings || {
|
||||||
var BestFriends;
|
PinnedGamesOn: true
|
||||||
|
|
||||||
let ContainerElement = `
|
|
||||||
<div class="card-body p-0 m-1 scrollFadeContainer d-flex"></div>`;
|
|
||||||
let GameContainerElement = `
|
|
||||||
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
|
|
||||||
<div class="card-body">
|
|
||||||
<img src=":Thumbnail" class="place-card-image">
|
|
||||||
<div>
|
|
||||||
<div class="mt-2 mb-1 place-card-title">
|
|
||||||
:GameName
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
let TitleElement = `
|
|
||||||
<div class="col">
|
|
||||||
<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')
|
|
||||||
|
|
||||||
let NewContainer = document.createElement('div');
|
|
||||||
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.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%;'
|
|
||||||
/*
|
|
||||||
BestFriendsContainer.style.display = 'none'
|
|
||||||
BestFriendsContainer.style.borderBottom = '1px solid #000'
|
|
||||||
BestFriendsContainer.style.paddingBottom = '10px'
|
|
||||||
BestFriendsContainer.style.marginBottom = '10px'
|
|
||||||
BestFriendsContainer.style.width = '100%'
|
|
||||||
*/
|
|
||||||
|
|
||||||
let Spacer = document.createElement('div')
|
|
||||||
Spacer.innerHTML = ' '
|
|
||||||
Spacer.style.width = '50px'
|
|
||||||
Spacer.prepend(BestFriendsContainer)
|
|
||||||
|
|
||||||
FriendContainer.prepend(BestFriendsContainer)
|
|
||||||
UpdateLocalData();
|
|
||||||
|
|
||||||
function UpdateLocalData() {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
|
||||||
Settings = result.PolyPlus_Settings || {PinnedGamesOn: true, BestFriendsOn: false}
|
|
||||||
});
|
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result) {
|
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
|
||||||
chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result) {
|
|
||||||
BestFriends = result.PolyPlus_BestFriends || [];
|
|
||||||
if (Settings.PinnedGamesOn === true) {
|
|
||||||
LoadPinnedGames();
|
|
||||||
} else {
|
|
||||||
NewContainer.style.display = 'none'
|
|
||||||
NewTitle.style.display = 'none'
|
|
||||||
}
|
|
||||||
if (Settings.BestFriendsOn === true) {
|
|
||||||
LoadBestFriends();
|
|
||||||
} else {
|
|
||||||
BestFriendsContainer.style.display = 'none'
|
|
||||||
Spacer.style.display = 'none'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadPinnedGames() {
|
|
||||||
var Existing = NewContainer.children[0].children
|
|
||||||
Array.from(Existing).forEach(element => {
|
|
||||||
element.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (PinnedGames.length === 0) {
|
|
||||||
NewContainer.style.display = 'none'
|
|
||||||
NewTitle.style.display = 'none'
|
|
||||||
} else {
|
|
||||||
NewContainer.style.display = ''
|
|
||||||
NewTitle.style.display = ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PinnedGames.forEach(element => {
|
if (Settings.PinnedGamesOn === true) {
|
||||||
fetch('https://api.polytoria.com/v1/places/' + element)
|
const PlaceIDs = result.PolyPlus_PinnedGames || [];
|
||||||
.then(response => response.json())
|
chrome.storage.local.get(['PolyPlus_PinnedGamesData'], async function(result){
|
||||||
.then(data => {
|
let PinnedGamesData = result['PolyPlus_PinnedGamesData'] || {data:undefined};
|
||||||
let GameName = data.name;
|
|
||||||
let GameThumbnail = data.thumbnail;
|
|
||||||
|
|
||||||
var NewGameContainer = document.createElement('a');
|
const PinnedGamesContainer = document.createElement('div')
|
||||||
NewGameContainer.innerHTML = GameContainerElement.replace(':GameName',GameName).replace(':Thumbnail',GameThumbnail);
|
PinnedGamesContainer.innerHTML = `
|
||||||
NewGameContainer.setAttribute('href', '/places/' + element);
|
<div class="row reqFadeAnim px-2 px-lg-0">
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="dash-ctitle2">Jump right back into your favorite games</h6>
|
||||||
|
<h5 class="dash-ctitle">Pinned Games</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card card-dash mcard mb-3">
|
||||||
|
<div class="card-body p-0 m-1 scrollFadeContainer" id="p+pinned_games_card">
|
||||||
|
<div class="text-center p-5">
|
||||||
|
<div class="spinner-border text-muted" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
if (new Date().getDate() >= new Date(data.updatedAt).getDate()) {
|
const RightSideColumn = document.getElementsByClassName('col-lg-8')[0];
|
||||||
console.log('Game has updated')
|
if (document.getElementsByClassName('home-event-container')[0] === undefined) {
|
||||||
|
RightSideColumn.insertBefore(PinnedGamesContainer, RightSideColumn.children[0]);
|
||||||
|
} else {
|
||||||
|
RightSideColumn.insertBefore(PinnedGamesContainer, RightSideColumn.children[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache for 5 minutes
|
||||||
|
if (PinnedGamesData === undefined || (new Date().getTime() - PinnedGamesData.requested > 300000)) {
|
||||||
|
PinnedGamesData.data = {}
|
||||||
|
for (let i = 0; i < PlaceIDs.length; i++) {
|
||||||
|
const PlaceID = PlaceIDs.toSorted((a, b) => b - a)[i]
|
||||||
|
const PlaceDetails = (await (await fetch('https://api.polytoria.com/v1/places/' + PlaceID)).json())
|
||||||
|
PinnedGamesData.data[PlaceID] = PlaceDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
NewContainer.children[0].appendChild(NewGameContainer);
|
chrome.storage.local.set({['PolyPlus_PinnedGamesData']: {
|
||||||
})
|
data: PinnedGamesData.data,
|
||||||
.catch(error => {
|
requested: new Date().getTime()
|
||||||
console.error('Error:', error);
|
}}, function(){});
|
||||||
});
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadBestFriends() {
|
const PinnedGamesCard = document.getElementById('p+pinned_games_card')
|
||||||
Array.from(document.querySelectorAll('[bestFriend]')).forEach(element => {
|
for (let i = 0; i < PlaceIDs.length; i++) {
|
||||||
element.removeAttribute('bestFriend')
|
const PlaceID = PlaceIDs.toSorted((a, b) => b - a)[i]
|
||||||
element.getElementsByClassName('friend-name')[0].style.color = 'initial';
|
const PlaceDetails = PinnedGamesData.data[PlaceID]
|
||||||
FriendContainer.appendChild(element)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (BestFriends.length === 0) {
|
const PlaceCard = document.createElement('a')
|
||||||
BestFriendsContainer.style.visibility = 'hidden'
|
PlaceCard.classList = 'd-none'
|
||||||
BestFriendsContainer.style.padding = '0px !important'
|
PlaceCard.href = '/places/' + PlaceID
|
||||||
BestFriendsContainer.style.margin = '0px !important'
|
PlaceCard.innerHTML = `
|
||||||
} else {
|
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
|
||||||
BestFriendsContainer.style.visibility = 'visible'
|
<div class="card-body">
|
||||||
BestFriendsContainer.style.padding = ''
|
<div class="ratings-header">
|
||||||
BestFriendsContainer.style.margin = ''
|
<img src="${PlaceDetails.thumbnail}" class="place-card-image" style="position: relative;">
|
||||||
|
<div class="p+pinned_games_playing" style="position: absolute;background: linear-gradient(to bottom, #000000f7, transparent, transparent, transparent);width: 100%;height: 100%;top: 0;left: 0;border-radius: 15px;padding-top: 12px;color: gray;font-size: 0.8rem;">
|
||||||
|
<i class="fa-duotone fa-users"></i>
|
||||||
|
<span>
|
||||||
|
${PlaceDetails.playing}
|
||||||
|
Playing
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="mt-2 mb-1 place-card-title">
|
||||||
|
${PlaceDetails.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
if (!PlaceDetails.isActive) {
|
||||||
|
const PlayerCountText = PlaceCard.getElementsByClassName('p+pinned_games_playing')[0]
|
||||||
|
PlayerCountText.children[0].classList = 'text-warning fa-duotone fa-lock'
|
||||||
|
PlayerCountText.children[1].remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
PinnedGamesCard.appendChild(PlaceCard)
|
||||||
|
}
|
||||||
|
PinnedGamesCard.children[0].remove()
|
||||||
|
PinnedGamesCard.classList.add('d-flex')
|
||||||
|
Array.from(PinnedGamesCard.children).forEach((place) => {place.classList.remove('d-none')})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BestFriends.forEach(element => {
|
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
let ExistingFriend = document.getElementById('friend-' + element)
|
(async () => {
|
||||||
if (ExistingFriend) {
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
ExistingFriend.setAttribute('bestFriend', 'true')
|
Utilities = Utilities.default;
|
||||||
ExistingFriend.getElementsByClassName('friend-name')[0].style.color = 'yellow';
|
|
||||||
BestFriendsContainer.prepend(ExistingFriend)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var SecondaryColumn = document.getElementsByClassName('col-lg-8')[0]
|
const TrendingItems = document.getElementById('home-trendingItems');
|
||||||
SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[0]);
|
for (let item of TrendingItems.children[1].getElementsByClassName('d-flex')[0].children) {
|
||||||
SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]);
|
const Price = item.getElementsByClassName('text-success')[0];
|
||||||
|
if (Price !== undefined) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.HomeFriendCountOn === true) {
|
||||||
|
chrome.storage.local.get(['PolyPlus_FriendCount'], async function(result){
|
||||||
|
let FriendCount = result['PolyPlus_FriendCount'].count;
|
||||||
|
|
||||||
|
// cache for 5 minutes
|
||||||
|
if (FriendCount === undefined || (new Date().getTime() - FriendCount.requested > 300000)) {
|
||||||
|
FriendCount = (await (await fetch('https://polytoria.com/api/friends?page=1')).json()).meta.total;
|
||||||
|
|
||||||
|
chrome.storage.local.set({['PolyPlus_FriendCount']: {
|
||||||
|
count: FriendCount,
|
||||||
|
requested: new Date().getTime()
|
||||||
|
}}, function(){});
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.HomeJoinFriendsButtonOn === true) {
|
||||||
|
const FriendsPopup = document.getElementById('friend-name')
|
||||||
|
const ChangeMutator = new MutationObserver(async function (list) {
|
||||||
|
for (let record of list) {
|
||||||
|
for (let node of record.addedNodes) {
|
||||||
|
if (node.tagName === 'A') {
|
||||||
|
const JoinButton = document.createElement('button')
|
||||||
|
JoinButton.classList = 'btn btn-success btn-sm'
|
||||||
|
JoinButton.style = 'position: absolute; top: 0; right: 0; z-index: 2000; font-size: 1.2rem;'
|
||||||
|
JoinButton.innerHTML = '<i class="fas fa-play"></i>'
|
||||||
|
node.parentElement.appendChild(JoinButton)
|
||||||
|
|
||||||
|
JoinButton.addEventListener('click', async function(){
|
||||||
|
const PlayingStatus = (await (await fetch('https://api.polytoria.com/v1/users/' + document.getElementById('friendsProfileLink').getAttribute('href').split('/')[2])).json()).playing;
|
||||||
|
|
||||||
|
const Token = (await (await fetch('https://polytoria.com/api/places/join', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
placeID: parseInt(node.getAttribute('href').split('/')[2]),
|
||||||
|
serverID: PlayingStatus.serverID
|
||||||
|
})
|
||||||
|
})).json())
|
||||||
|
|
||||||
|
if (!Token.success) {
|
||||||
|
alert(Token.message);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = 'polytoria://client/' + Token.token
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ChangeMutator.observe(FriendsPopup, {childList: true})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -1,47 +1,47 @@
|
||||||
HandleExpandMessages()
|
ExpandMessages();
|
||||||
|
|
||||||
function HandleExpandMessages() {
|
function ExpandMessages() {
|
||||||
const Messages = document.getElementById('messages')
|
const Messages = document.getElementById('messages');
|
||||||
|
|
||||||
for (let message of Messages.children) {
|
for (let message of Messages.children) {
|
||||||
let Expanded = false
|
let Expanded = false;
|
||||||
let ContentDiv = null
|
let ContentDiv = null;
|
||||||
|
|
||||||
const ViewButton = message.querySelector('a.btn[href^="/inbox/messages"]')
|
const ViewButton = message.querySelector('a.btn[href^="/inbox/messages"]');
|
||||||
const MessageID = ViewButton.getAttribute('href').split('/')[3]
|
const MessageID = ViewButton.getAttribute('href').split('/')[3];
|
||||||
|
|
||||||
const ExpandButton = document.createElement('button')
|
const ExpandButton = document.createElement('button');
|
||||||
ExpandButton.classList = 'btn btn-outline-warning px-4 mt-1'
|
ExpandButton.classList = 'btn btn-outline-warning px-4 mt-1';
|
||||||
ExpandButton.innerText = 'Expand'
|
ExpandButton.innerText = 'Expand';
|
||||||
ViewButton.parentElement.appendChild(ExpandButton)
|
ViewButton.parentElement.appendChild(ExpandButton);
|
||||||
|
|
||||||
ExpandButton.addEventListener('click', function(){
|
ExpandButton.addEventListener('click', function () {
|
||||||
if (ContentDiv === null) {
|
if (ContentDiv === null) {
|
||||||
fetch('https://polytoria.com/inbox/messages/'+MessageID)
|
fetch('https://polytoria.com/inbox/messages/' + MessageID)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Network not ok')
|
throw new Error('Network not ok');
|
||||||
}
|
}
|
||||||
return response.text()
|
return response.text();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
const Doc = new DOMParser().parseFromString(data, 'text/html')
|
const Doc = new DOMParser().parseFromString(data, 'text/html');
|
||||||
const MessageContent = Doc.querySelector('p.mb-0').innerText
|
const MessageContent = Doc.querySelector('p.mb-0').innerText;
|
||||||
|
|
||||||
ContentDiv = document.createElement('div')
|
ContentDiv = document.createElement('div');
|
||||||
ContentDiv.classList = 'py-2'
|
ContentDiv.classList = 'py-2';
|
||||||
ContentDiv.innerText = MessageContent
|
ContentDiv.innerText = MessageContent;
|
||||||
message.appendChild(ContentDiv)
|
message.appendChild(ContentDiv);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.log(error)
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Expanded = !Expanded
|
Expanded = !Expanded;
|
||||||
|
|
||||||
ExpandButton.innerText = (Expanded === false) ? 'Expand' : 'Minimize'
|
ExpandButton.innerText = Expanded === false ? 'Expand' : 'Minimize';
|
||||||
ContentDiv.style.display = (Expanded === false) ? 'none' : 'block'
|
ContentDiv.style.display = Expanded === false ? 'none' : 'block';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,186 +1,352 @@
|
||||||
if (window.location.pathname.split('/')[3] === "inventory") {
|
/*
|
||||||
const UserID = window.location.pathname.split('/')[2]
|
Proper pagination will be added in v1.2.3
|
||||||
if (UserID === JSON.parse(window.localStorage.getItem('account_info')).ID) {
|
*/
|
||||||
let Nav = document.getElementsByClassName('nav-pills')[0]
|
|
||||||
let WishlistNav = document.createElement('li')
|
|
||||||
WishlistNav.classList.add('nav-item')
|
|
||||||
WishlistNav.innerHTML = `
|
|
||||||
<a href="wishlist/" class="nav-link">
|
|
||||||
<i class="fa-regular fa-sparkles me-1"></i>
|
|
||||||
<span class="pilltitle">Item Wishlist</span>
|
|
||||||
</a>
|
|
||||||
`
|
|
||||||
Nav.appendChild(WishlistNav)
|
|
||||||
|
|
||||||
if (window.location.pathname.split('/')[4] === "wishlist") {
|
Username = window.location.pathname.split('/')[2];
|
||||||
const ItemGrid = document.getElementsByClassName('itemgrid')[0]
|
let UserID;
|
||||||
const ItemCardContents = `
|
let ItemGrid;
|
||||||
<a href="/store/:ItemID" class="text-reset">
|
|
||||||
<div class="card mb-2">
|
|
||||||
:LimitedTag
|
|
||||||
<div class="card-body">
|
|
||||||
<img src=":ItemThumbnail" class="img-fluid rounded">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h6 class="text-truncate mb-0">
|
|
||||||
:ItemName
|
|
||||||
</h6>
|
|
||||||
</a>
|
|
||||||
<small class="text-muted d-block mb-1">
|
|
||||||
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 => {
|
let _Utilities;
|
||||||
element.remove();
|
|
||||||
});
|
|
||||||
Array.from(Nav.children).forEach(element => {
|
|
||||||
element = element.children[0]
|
|
||||||
if (!(element === WishlistNav)) {
|
|
||||||
if (element.classList.contains('active')) {
|
|
||||||
element.classList.remove('active')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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;">
|
|
||||||
<option value="any">Any</option>
|
|
||||||
<option value="hat">Hat</option>
|
|
||||||
<option value="face">Faces</option>
|
|
||||||
<option value="tool">Tools</option>
|
|
||||||
<option value="shirt">Shirt</option>
|
|
||||||
<option value="pants">Pants</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<input id="polyplus-itemwish-searchbar" type="text" class="form-control bg-dark" placeholder="Search...">
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" value="" id="polyplus-itemwish-isLimited">
|
|
||||||
<label class="form-check-label" for="polyplus-itemwish-isLimited">
|
|
||||||
Is Limited?
|
|
||||||
<span class="text-muted" style="font-size: 0.65rem; display: block;">Items that are limited</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" value="" id="polyplus-itemwish-isAvailable">
|
|
||||||
<label class="form-check-label" for="polyplus-itemwish-isAvailable">
|
|
||||||
Is Available?
|
|
||||||
<span class="text-muted" style="font-size: 0.65rem; display: block; width: 170px;">Items that are equal to or less than the budget (excluding limiteds)</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
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')
|
if (window.location.pathname.split('/')[3] === 'inventory') {
|
||||||
let SearchBar = document.getElementById('polyplus-itemwish-searchbar')
|
!(async () => {
|
||||||
let IsLimited = document.getElementById('polyplus-itemwish-isLimited')
|
UserID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + Username )).json()).id;
|
||||||
let IsAvailable = document.getElementById('polyplus-itemwish-isAvailable')
|
ItemGrid = document.getElementsByClassName('itemgrid')[0];
|
||||||
|
|
||||||
Type.addEventListener('change', function(){
|
/*
|
||||||
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
|
Rewritten item wishlist function will take in the data with a parameter instead
|
||||||
});
|
*/
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){
|
||||||
|
_Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
_Utilities = _Utilities.default
|
||||||
|
|
||||||
SearchBar.addEventListener('change', function(){
|
Settings = result.PolyPlus_Settings
|
||||||
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
|
|
||||||
});
|
|
||||||
|
|
||||||
IsLimited.addEventListener('change', function(){
|
const Nav = document.getElementsByClassName('nav-pills')[0];
|
||||||
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
|
|
||||||
});
|
|
||||||
|
|
||||||
IsAvailable.addEventListener('change', function(){
|
if (Settings.ItemWishlistOn && Username === JSON.parse(window.localStorage.getItem('p+account_info')).Username) {
|
||||||
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked)
|
let WishlistNav = document.createElement('li');
|
||||||
});
|
WishlistNav.classList.add('nav-item');
|
||||||
|
WishlistNav.innerHTML = `
|
||||||
|
<a href="${ (window.location.pathname.split('/')[4] !== '') ? '../wishlist/' : 'wishlist/' }" class="nav-link">
|
||||||
|
<i class="fa-regular fa-list me-1"></i>
|
||||||
|
<span class="pilltitle">Item Wishlist</span>
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
Nav.appendChild(WishlistNav);
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_ItemWishlist'], function(result){
|
if (window.location.pathname.split('/')[4] === 'wishlist') {
|
||||||
let Wishlist = result.PolyPlus_ItemWishlist || [];
|
Array.from(Nav.children).forEach((element) => {
|
||||||
console.log('wishlist: ', Wishlist)
|
element = element.children[0];
|
||||||
Wishlist.forEach(element => {
|
if (!(element === WishlistNav)) {
|
||||||
let NewItemCard = document.createElement('div')
|
if (element.classList.contains('active')) {
|
||||||
NewItemCard.classList = 'px-0'
|
element.classList.remove('active');
|
||||||
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)
|
WishlistNav.children[0].classList.add('active');
|
||||||
if (data.isLimited === true) {
|
|
||||||
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.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemGrid.appendChild(NewItemCard)
|
ItemWishlist()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NewItemCard.getElementsByClassName('polyplus-itemwish-removebtn')[0].addEventListener('click', function(){
|
if (Settings.CollectibleInventoryCatOn) {
|
||||||
let Index = Wishlist.indexOf(parseInt(NewItemCard.getAttribute('data-id')))
|
let CollectibleNav = document.createElement('li');
|
||||||
if (Index === -1) {
|
CollectibleNav.classList.add('nav-item');
|
||||||
NewItemCard.remove();
|
CollectibleNav.innerHTML = `
|
||||||
return
|
<a href="${ (window.location.pathname.split('/')[4] !== '') ? '../collectibles/' : 'collectibles/' }" class="nav-link">
|
||||||
} else {
|
<i class="fa-regular fa-sparkles me-1"></i>
|
||||||
Wishlist.splice(Index, 1)
|
<span class="pilltitle">Collectibles</span>
|
||||||
console.log(Wishlist)
|
</a>
|
||||||
NewItemCard.remove();
|
`;
|
||||||
}
|
Nav.appendChild(CollectibleNav);
|
||||||
chrome.storage.sync.set({'PolyPlus_ItemWishlist': Wishlist, arrayOrder: true}, function() {
|
|
||||||
console.log('ItemWishlist successfully saved: ' + ItemWishlist)
|
if (window.location.pathname.split('/')[4] === 'collectibles') {
|
||||||
});
|
Array.from(Nav.children).forEach((element) => {
|
||||||
});
|
element = element.children[0];
|
||||||
})
|
if (!(element === CollectibleNav)) {
|
||||||
.catch(error => {
|
if (element.classList.contains('active')) {
|
||||||
console.error('Error:', error);
|
element.classList.remove('active');
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
}
|
CollectibleNav.children[0].classList.add('active');
|
||||||
}
|
|
||||||
|
let HoardedCard = document.createElement('li');
|
||||||
|
HoardedCard.classList.add('nav-item');
|
||||||
|
HoardedCard.classList.add('text-center');
|
||||||
|
HoardedCard.innerHTML = `
|
||||||
|
<h6 class="section-title mt-3 px-2">
|
||||||
|
Hoarded Items
|
||||||
|
</h6>
|
||||||
|
<div class="card bg-dark mt-2">
|
||||||
|
<div class="card-body" id="p+hoarded_card"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
Nav.appendChild(HoardedCard);
|
||||||
|
|
||||||
|
CollectibleCategory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
function Update(type, query, isLimited, isAvailable) {
|
/*
|
||||||
let ItemGrid = document.getElementsByClassName('itemgrid')[0]
|
Item Wishlist will be rewritten in v1.2.3
|
||||||
let BrickBalance = parseInt(JSON.parse(window.localStorage.getItem('account_info')).Bricks)
|
*/
|
||||||
query = query.toLowerCase();
|
function ItemWishlist() {
|
||||||
let Results = Array.from(ItemGrid.children)
|
const ItemGrid = document.getElementsByClassName('itemgrid')[0];
|
||||||
for (let i = 0; i < Results.length; i++) {
|
const ItemCardContents = `
|
||||||
let Show = true
|
<a href="/store/:ItemID" class="text-reset">
|
||||||
|
<div class="card mb-2">
|
||||||
|
:LimitedTag
|
||||||
|
<div class="card-body">
|
||||||
|
<img src=":ItemThumbnail" class="img-fluid rounded">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h6 class="text-truncate mb-0">
|
||||||
|
:ItemName
|
||||||
|
</h6>
|
||||||
|
</a>
|
||||||
|
<small class="text-muted d-block mb-1">
|
||||||
|
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>
|
||||||
|
`;
|
||||||
|
|
||||||
console.log('type: ', type)
|
ItemGrid.innerHTML = ''
|
||||||
if (!(type === 'any')) {
|
document.getElementsByClassName('pagination')[0].remove()
|
||||||
console.log('isn\'t any')
|
const Search = document.createElement('div');
|
||||||
if (!(Results[i].getAttribute('data-type') === type)) {Show = false}
|
Search.classList = 'row';
|
||||||
}
|
Search.innerHTML = `
|
||||||
|
<div class="col-auto">
|
||||||
|
<select class="form-select" id="polyplus-itemwish-type" style="width: 150px;">
|
||||||
|
<option value="any">Any</option>
|
||||||
|
<option value="hat">Hat</option>
|
||||||
|
<option value="face">Faces</option>
|
||||||
|
<option value="tool">Tools</option>
|
||||||
|
<option value="shirt">Shirt</option>
|
||||||
|
<option value="pants">Pants</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input id="polyplus-itemwish-searchbar" type="text" class="form-control bg-dark" placeholder="Search...">
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="polyplus-itemwish-isLimited">
|
||||||
|
<label class="form-check-label" for="polyplus-itemwish-isLimited">
|
||||||
|
Is Collectible?
|
||||||
|
<span class="text-muted" style="font-size: 0.65rem; display: block;">Items that are collectible</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="polyplus-itemwish-isAvailable">
|
||||||
|
<label class="form-check-label" for="polyplus-itemwish-isAvailable">
|
||||||
|
Is Available?
|
||||||
|
<span class="text-muted" style="font-size: 0.65rem; display: block; width: 170px;">Items that are equal to or less than the budget (excluding limiteds)</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
ItemGrid.parentElement.prepend(document.createElement('br'), ItemGrid.parentElement.children[0]);
|
||||||
|
ItemGrid.parentElement.prepend(Search, ItemGrid.parentElement.children[0]);
|
||||||
|
|
||||||
if (!(Results[i].getAttribute('data-name').toLowerCase().startsWith(query))) {Show = false}
|
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');
|
||||||
|
|
||||||
if (isLimited === true) {
|
Type.addEventListener('change', function () {
|
||||||
if (!(Results[i].getAttribute('data-limited') === 'true')) {Show = false}
|
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
|
||||||
}
|
});
|
||||||
|
|
||||||
if (isAvailable === true) {
|
SearchBar.addEventListener('change', function () {
|
||||||
if (!(parseInt(Results[i].getAttribute('data-price')) <= BrickBalance)) {Show = false}
|
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
|
||||||
}
|
});
|
||||||
|
|
||||||
if (Show === true) {
|
IsLimited.addEventListener('change', function () {
|
||||||
Results[i].style.display = 'block'
|
Update(Type.options[Type.selectedIndex].value, SearchBar.value, IsLimited.checked, IsAvailable.checked);
|
||||||
} else {
|
});
|
||||||
Results[i].style.display = 'none'
|
|
||||||
}
|
IsAvailable.addEventListener('change', function () {
|
||||||
}
|
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';
|
||||||
|
fetch('https://api.polytoria.com/v1/store/' + 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);
|
||||||
|
if (data.isLimited === true) {
|
||||||
|
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.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemGrid.appendChild(NewItemCard);
|
||||||
|
|
||||||
|
NewItemCard.getElementsByClassName('polyplus-itemwish-removebtn')[0].addEventListener('click', function () {
|
||||||
|
let Index = Wishlist.indexOf(parseInt(NewItemCard.getAttribute('data-id')));
|
||||||
|
if (Index === -1) {
|
||||||
|
NewItemCard.remove();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const Update = function(type, query, isLimited, isAvailable) {
|
||||||
|
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);
|
||||||
|
for (let i = 0; i < Results.length; i++) {
|
||||||
|
let Show = true;
|
||||||
|
|
||||||
|
console.log('type: ', type);
|
||||||
|
if (!(type === 'any')) {
|
||||||
|
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 (isLimited === true) {
|
||||||
|
if (!(Results[i].getAttribute('data-limited') === 'true')) {
|
||||||
|
Show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAvailable === true) {
|
||||||
|
if (!(parseInt(Results[i].getAttribute('data-price')) <= BrickBalance)) {
|
||||||
|
Show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Show === true) {
|
||||||
|
Results[i].style.display = 'block';
|
||||||
|
} else {
|
||||||
|
Results[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function CollectibleCategory() {
|
||||||
|
ItemGrid.innerHTML = ''
|
||||||
|
document.getElementsByClassName('pagination')[0].remove()
|
||||||
|
const CollectibleItemTypes = [
|
||||||
|
"hat",
|
||||||
|
"face",
|
||||||
|
"tool"
|
||||||
|
]
|
||||||
|
const Collectibles = []
|
||||||
|
|
||||||
|
for (let type of CollectibleItemTypes) {
|
||||||
|
const InitialInventory = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=' + type + '&limit=100')).json())
|
||||||
|
Collectibles.push(...InitialInventory.inventory.filter((x) => x.asset.isLimited === true))
|
||||||
|
|
||||||
|
if (InitialInventory.pages > 1) {
|
||||||
|
if (InitialInventory.pages > 12) {
|
||||||
|
InitialInventory.pages = 12
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let page = 2; page < InitialInventory.pages; page++) {
|
||||||
|
const PageResult = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=' + type + '&limit=100&page=' + page)).json())
|
||||||
|
Collectibles.push(...PageResult.inventory.filter((x) => x.asset.isLimited === true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ItemMultiples = []
|
||||||
|
Collectibles.forEach(item => {
|
||||||
|
const Multiple = ItemMultiples.findIndex((x) => x.asset.id === item.asset.id)
|
||||||
|
if (Multiple !== -1) {
|
||||||
|
ItemMultiples[Multiple].copies++
|
||||||
|
ItemMultiples[Multiple].serials.push(item.serial)
|
||||||
|
} else { ItemMultiples.push({asset: item.asset, copies: 1, serials: [item.serial]}) }
|
||||||
|
|
||||||
|
const ItemColumn = document.createElement('div')
|
||||||
|
ItemColumn.classList = 'px-0'
|
||||||
|
ItemColumn.innerHTML = `
|
||||||
|
<a href="/store/${item.asset.id}" class="text-reset">
|
||||||
|
<div class="card mb-2">
|
||||||
|
<div class="ribbon ribbon-limited ribbon-top-right"><span>Limited</span></div>
|
||||||
|
<div class="card-body">
|
||||||
|
<img src="${item.asset.thumbnail}" class="img-fluid rounded">
|
||||||
|
<span class="badge bg-dark" style="
|
||||||
|
font-weight: lighter;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: 5px;
|
||||||
|
">#${item.serial}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h6 class="text-truncate mb-0">
|
||||||
|
${item.asset.name}
|
||||||
|
</h6>
|
||||||
|
</a>
|
||||||
|
<small class="text-muted d-block mb-1">
|
||||||
|
by <a href="/u/Polytoria" class="text-muted">Polytoria</a>
|
||||||
|
</small>
|
||||||
|
`
|
||||||
|
ItemGrid.appendChild(ItemColumn)
|
||||||
|
})
|
||||||
|
|
||||||
|
const Hoarded = ItemMultiples.filter((x) => x.copies > 1)
|
||||||
|
|
||||||
|
const HoardedCard = document.getElementById('p+hoarded_card')
|
||||||
|
Hoarded.forEach(item => {
|
||||||
|
const ListElement = document.createElement('div')
|
||||||
|
ListElement.classList = 'mb-1 mb-2'
|
||||||
|
ListElement.innerHTML = `
|
||||||
|
<a href="/store/${item.asset.id}" style="font-size: 0.8rem; color: #454545 !important;">
|
||||||
|
<b>${item.asset.name}</b>
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
<span>
|
||||||
|
${item.copies} copies <i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-title="#${item.serials.sort((a, b) => a - b).join(', #')}"></i>
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
HoardedCard.appendChild(ListElement)
|
||||||
|
})
|
||||||
|
|
||||||
|
_Utilities.InjectResource("registerTooltips")
|
||||||
}
|
}
|
||||||
384
js/account/profile.js
Executable file
|
|
@ -0,0 +1,384 @@
|
||||||
|
let Username = window.location.pathname.split('/')[2];
|
||||||
|
let Blocked = false;
|
||||||
|
|
||||||
|
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;
|
||||||
|
let FavoriteBtn;
|
||||||
|
let CalculateButton;
|
||||||
|
let AvatarIFrame;
|
||||||
|
|
||||||
|
let Utilities;
|
||||||
|
|
||||||
|
if (Username) {
|
||||||
|
(async () => {
|
||||||
|
UserID = (await (await fetch('https://api.'+window.location.hostname+'/v1/users/find?username=' + Username )).json());
|
||||||
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default;
|
||||||
|
|
||||||
|
if (document.querySelector('.card .fa-ban')) {
|
||||||
|
Blocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
||||||
|
Settings = result.PolyPlus_Settings || {};
|
||||||
|
|
||||||
|
const InfoColumns = document.getElementById('user-stats-card');
|
||||||
|
const UserIDRow = document.createElement('div')
|
||||||
|
UserIDRow.classList = 'mb-1 text-start'
|
||||||
|
UserIDRow.innerHTML = `
|
||||||
|
<b><i class="fa fa-hashtag text-center d-inline-block" style="width:1.2em"></i> Player ID</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${UserID.id} <a id="copy" href="#copy"><i class="fad fa-copy" style="margin-left: 5px;"></i></a>
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
if (!Blocked) {
|
||||||
|
InfoColumns.children[0].insertBefore(UserIDRow, InfoColumns.children[0].children[1]);
|
||||||
|
} else {
|
||||||
|
if (Settings.MoreBlockedDetailsOn) {
|
||||||
|
const BlockedCard = document.querySelector('.card-body:has(.fa-ban)')
|
||||||
|
BlockedCard.appendChild(document.createElement('hr'))
|
||||||
|
|
||||||
|
const AccountInfo = (await (await fetch('https://api.'+window.location.hostname+'/v1/users/' + UserID.id )).json());
|
||||||
|
|
||||||
|
const AccountCreatedRow = document.createElement('div')
|
||||||
|
AccountCreatedRow.classList = 'mb-1 text-start'
|
||||||
|
AccountCreatedRow.innerHTML = `
|
||||||
|
<b><i class="fad fa-calendar text-center d-inline-block" style="width:1.2em"></i> Join date</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${ ["January","February","March","April","May","June","July","August","September","November","December"][new Date(AccountInfo.registeredAt).getMonth() - 1] + " " + new Date(AccountInfo.registeredAt).getDate() + ", " + new Date(AccountInfo.registeredAt).getFullYear() }
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
|
||||||
|
BlockedCard.appendChild(UserIDRow)
|
||||||
|
BlockedCard.appendChild(AccountCreatedRow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CopyButton = UserIDRow.getElementsByTagName('a')[0]
|
||||||
|
CopyButton.addEventListener('click', function(){
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(UserID.id)
|
||||||
|
.then(() => {
|
||||||
|
CopyButton.classList.add('text-success')
|
||||||
|
CopyButton.children[0].classList = 'fa-duotone fa-circle-check'
|
||||||
|
CopyButton.children[0].style.marginLeft = '3px'
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
CopyButton.classList.remove('text-success')
|
||||||
|
CopyButton.children[0].classList = 'fad fa-copy'
|
||||||
|
CopyButton.children[0].style.marginLeft = '5px'
|
||||||
|
}, 1500);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
|
IRLPrice();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.BestFriendsOn === true) {
|
||||||
|
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.innerHTML = `
|
||||||
|
<a class="text-decoration-underline text-success" style="text-decoration-color: rgb(15, 132, 79) !important;">$ calculate</a>
|
||||||
|
`;
|
||||||
|
AvatarHeading.appendChild(CalculateButton);
|
||||||
|
|
||||||
|
Utilities.InjectResource('registerTooltips');
|
||||||
|
|
||||||
|
let Calculating = false;
|
||||||
|
CalculateButton.addEventListener('click', function () {
|
||||||
|
if (Calculating === false) {
|
||||||
|
Calculating = true;
|
||||||
|
CalculateButton.innerText = '$ Calculating...';
|
||||||
|
OutfitCost();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarIFrame = document.getElementById('user-avatar-card').getElementsByTagName('iframe')[0]
|
||||||
|
if (Settings.AvatarDimensionToggleOn === true || 1 === 1) {
|
||||||
|
const AvatarCard = document.getElementById('user-avatar-card')
|
||||||
|
const ToggleButton = document.createElement('button')
|
||||||
|
ToggleButton.classList = 'btn btn-primary btn-sm 3dviewtoggler isactive'
|
||||||
|
ToggleButton.style = 'position: absolute; right: 15px; margin-top: 20px;'
|
||||||
|
ToggleButton.innerHTML = '<i class="toggleIcn fad fa-image"></i>'
|
||||||
|
AvatarCard.getElementsByClassName('position-relative')[0].insertBefore(ToggleButton, AvatarIFrame)
|
||||||
|
|
||||||
|
ToggleButton.addEventListener('click', async function(){
|
||||||
|
if (ToggleButton.children[0].classList.contains('fa-image')) {
|
||||||
|
if (document.getElementById('polyplus-2davatar')) {
|
||||||
|
const AvatarImage = document.getElementById('polyplus-2davatar')
|
||||||
|
|
||||||
|
AvatarImage.width = AvatarIFrame.offsetWidth
|
||||||
|
AvatarImage.height = AvatarIFrame.offsetHeight
|
||||||
|
AvatarImage.style.display = 'block'
|
||||||
|
AvatarIFrame.style.display = 'none'
|
||||||
|
|
||||||
|
ToggleButton.children[0].classList = 'toggleIcn fad fa-360-degrees'
|
||||||
|
} else {
|
||||||
|
const AvatarImage = document.createElement('img')
|
||||||
|
AvatarImage.id = 'polyplus-2davatar'
|
||||||
|
AvatarImage.width = AvatarIFrame.offsetWidth
|
||||||
|
AvatarImage.height = AvatarIFrame.offsetHeight
|
||||||
|
AvatarImage.style.padding = '20px'
|
||||||
|
|
||||||
|
const UserDetails = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID.id)).json())
|
||||||
|
AvatarImage.src = UserDetails.thumbnail.avatar
|
||||||
|
|
||||||
|
AvatarIFrame.style.display = 'none'
|
||||||
|
|
||||||
|
const CustomBadge = document.querySelector('#user-avatar-card .badge:has(.pi)')
|
||||||
|
if (CustomBadge === null) {
|
||||||
|
AvatarCard.children[0].insertBefore(AvatarImage, AvatarCard.getElementsByClassName('user-badges')[0])
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
AvatarCard.children[0].insertBefore(AvatarImage, CustomBadge)
|
||||||
|
} catch(error) {
|
||||||
|
AvatarCard.children[0].insertBefore(AvatarImage, CustomBadge.parentElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToggleButton.children[0].classList = 'toggleIcn fad fa-360-degrees'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.getElementById('polyplus-2davatar').style.display = 'none'
|
||||||
|
AvatarIFrame.style.display = 'block'
|
||||||
|
ToggleButton.children[0].classList = 'toggleIcn fad fa-image'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (new URLSearchParams(window.location.search).get('anniversary') === '1') {
|
||||||
|
const JoinDateRow = document.querySelector('#user-stats-card .mb-1:has(.fa-calendar)')
|
||||||
|
const BirthdayCard = document.createElement('div')
|
||||||
|
BirthdayCard.classList = 'card card-themed card-player-birthday mb-2'
|
||||||
|
|
||||||
|
const AnniversaryNumber = (new Date().getFullYear() - new Date(JoinDateRow.children[1].innerText).getFullYear())
|
||||||
|
BirthdayCard.innerHTML = `
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="fw-semibold text-birthday-gradient">
|
||||||
|
<i class="fas fa-cake me-1"></i> It's my ${AnniversaryNumber + (AnniversaryNumber % 10 === 1 && AnniversaryNumber % 100 !== 11 ? 'st' : AnniversaryNumber % 10 === 2 && AnniversaryNumber % 100 !== 12 ? 'nd' : AnniversaryNumber % 10 === 3 && AnniversaryNumber % 100 !== 13 ? 'rd' : 'th')} Polytoria anniversary!
|
||||||
|
</div>
|
||||||
|
<a href="/inbox/messages/${UserID.id}/compose?anniversaryPreset=${AnniversaryNumber}" class="btn btn-sm btn-outline-light mt-2"><i class="fas fa-hands-clapping me-1"></i> Send ${UserID.username} congrats</a>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
document.getElementById('user-avatar-card').parentElement.insertBefore(BirthdayCard, document.getElementById('user-avatar-card'))
|
||||||
|
JoinDateRow.children[1].innerHTML = '<i class="fas fa-cake"></i> ' + JoinDateRow.children[1].innerHTML
|
||||||
|
JoinDateRow.children[1].classList.add('text-birthday-gradient')
|
||||||
|
JoinDateRow.children[1].classList.add('fw-semibold')
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (AvatarIFrame === null) {
|
||||||
|
AvatarIFrame = document.getElementById('user-avatar-card').getElementsByTagName('iframe')[0]
|
||||||
|
}
|
||||||
|
const DropdownMenu = document.getElementsByClassName('dropdown-menu dropdown-menu-right')[0];
|
||||||
|
|
||||||
|
const CopyItem = document.createElement('a');
|
||||||
|
CopyItem.classList = 'dropdown-item text-primary';
|
||||||
|
CopyItem.href = '#';
|
||||||
|
CopyItem.innerHTML = `
|
||||||
|
<i class="fa-duotone fa-book"></i>
|
||||||
|
Copy 3D Avatar URL
|
||||||
|
`;
|
||||||
|
DropdownMenu.appendChild(CopyItem);
|
||||||
|
|
||||||
|
CopyItem.addEventListener('click', function () {
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(AvatarIFrame.src)
|
||||||
|
.then(() => {
|
||||||
|
alert('Successfully copied 3D avatar URL!');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure to copy 3D avatar URL.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ShareItem.addEventListener('click', function () {
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText('Hey! Look at my Polytoria avatar in 3D [here](' + AvatarIFrame.src + ')!')
|
||||||
|
.then(() => {
|
||||||
|
alert('Successfully copied sharable 3D avatar URL!');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure to copy sharable 3D avatar URL.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (Username && Username[0] === '@') {
|
||||||
|
const Username = window.location.pathname.split('/')[2].substring(1);
|
||||||
|
|
||||||
|
let Reference = new URLSearchParams(new URL(window.location.href).search);
|
||||||
|
if (!Reference.has('ref')) {
|
||||||
|
Reference = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('https://api.polytoria.com/v1/users/find?username=' + Username)
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
window.location.href = window.location.origin + decodeURIComponent(Reference.get('ref'));
|
||||||
|
} else {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
window.location.href = 'https://polytoria.com/users/' + data.id;
|
||||||
|
})
|
||||||
|
.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>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function BestFriends() {
|
||||||
|
chrome.storage.sync.get(['PolyPlus_BestFriends'], function (result) {
|
||||||
|
BestFriends = result.PolyPlus_BestFriends || [];
|
||||||
|
|
||||||
|
FavoriteBtn = document.createElement('button');
|
||||||
|
FavoriteBtn.classList = 'btn btn-warning btn-sm ml-2';
|
||||||
|
if (!(BestFriends.length === Utilities.Limits.BestFriends)) {
|
||||||
|
if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID.id))) {
|
||||||
|
FavoriteBtn.innerText = 'Remove Best Friend Status';
|
||||||
|
} else {
|
||||||
|
FavoriteBtn.innerText = 'Best Friend';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FavoriteBtn.innerText = 'Remove Best Friend Status (max ' + Utilities.Limits.BestFriends + '/' + Utilities.Limits.BestFriends + ')';
|
||||||
|
}
|
||||||
|
if (UserID.id !== 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.id, FavoriteBtn);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
FavoriteBtn.style.display = 'none';
|
||||||
|
}
|
||||||
|
document.querySelectorAll('.section-title.px-3.px-lg-0.mt-3')[0].appendChild(FavoriteBtn);
|
||||||
|
|
||||||
|
function Fav(UserID, btn) {
|
||||||
|
if (UserID.id === 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 || [];
|
||||||
|
const index = BestFriends.indexOf(parseInt(UserID.id));
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
// Number exists, remove it
|
||||||
|
BestFriends.splice(index, 1);
|
||||||
|
btn.innerText = 'Best Friend';
|
||||||
|
console.log('Number', parseInt(UserID.id), 'removed from BestFriends');
|
||||||
|
} else {
|
||||||
|
// Number doesn't exist, add it
|
||||||
|
BestFriends.push(parseInt(UserID.id));
|
||||||
|
btn.innerText = 'Remove Best Friend Status';
|
||||||
|
console.log('Number', parseInt(UserID.id), 'added to BestFriends');
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.storage.sync.set({PolyPlus_BestFriends: BestFriends, arrayOrder: true}, function () {
|
||||||
|
console.log('BestFriends saved successfully!');
|
||||||
|
setTimeout(function () {
|
||||||
|
btn.removeAttribute('disabled');
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.storage.onChanged.addListener(function (changes, namespace) {
|
||||||
|
if ('PolyPlus_BestFriends' in changes) {
|
||||||
|
chrome.storage.sync.get(['PolyPlus_BestFriends'], function (result) {
|
||||||
|
BestFriends = result.PolyPlus_BestFriends || [];
|
||||||
|
|
||||||
|
if (!(BestFriends.length === Utilities.Limits.BestFriends)) {
|
||||||
|
if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID.id))) {
|
||||||
|
FavoriteBtn.innerText = 'Remove Best Friend Status';
|
||||||
|
} else {
|
||||||
|
FavoriteBtn.innerText = 'Best Friend';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 () {
|
||||||
|
console.log('BestFriends saved successfully!');
|
||||||
|
setTimeout(function () {
|
||||||
|
btn.removeAttribute('disabled');
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function OutfitCost() {
|
||||||
|
const AvatarCost = {
|
||||||
|
Total: 0,
|
||||||
|
Collectibles: 0,
|
||||||
|
Offsale: 0,
|
||||||
|
HasProfileTheme: false
|
||||||
|
};
|
||||||
|
for (let item of AvatarRow.children) {
|
||||||
|
const ItemID = item.getElementsByTagName('a')[0].href.split('/')[4];
|
||||||
|
await fetch('https://api.polytoria.com/v1/store/' + ItemID)
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
let Price = data.price;
|
||||||
|
if (data.isLimited === true) {
|
||||||
|
AvatarCost.Collectibles += 1;
|
||||||
|
Price = data.averagePrice;
|
||||||
|
} else if (data.sales === 0) {
|
||||||
|
AvatarCost.Offsale += 1;
|
||||||
|
Price = 0;
|
||||||
|
} else if (data.type === 'profileTheme') {
|
||||||
|
AvatarCost.HasProfileTheme = true;
|
||||||
|
Price = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AvatarCost.Total += Price;
|
||||||
|
})
|
||||||
|
.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' : ''})`;
|
||||||
|
|
||||||
|
CalculateButton.remove();
|
||||||
|
AvatarHeading.appendChild(ResultText);
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,29 @@
|
||||||
setTimeout(function () {}, 100)
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
|
if (result.PolyPlus_Settings.MoreSearchFiltersOn === true) {
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
const BlockedUsersCard = document.querySelector('.card-body:has([action^="/api/users/"])');
|
||||||
if (result.PolyPlus_Settings.MoreSearchFiltersOn === true) {
|
const InputGroup = document.createElement('div');
|
||||||
let BlockedUsersCard = document.getElementsByClassName('card-body')[1]
|
InputGroup.classList = 'input-group mb-2';
|
||||||
let InputGroup = document.createElement('div')
|
InputGroup.innerHTML = `
|
||||||
InputGroup.classList = 'input-group mb-2'
|
|
||||||
InputGroup.innerHTML = `
|
|
||||||
<input id="blocked-users-search" type="text" class="form-control bg-dark" placeholder="Search blocked users...">
|
<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>
|
<button id="blocked-users-confirm" class="btn btn-secondary"><i class="fad fa-search"></i></button>
|
||||||
`
|
`;
|
||||||
BlockedUsersCard.insertBefore(InputGroup, BlockedUsersCard.children[0])
|
BlockedUsersCard.insertBefore(InputGroup, BlockedUsersCard.children[0]);
|
||||||
let SearchBar = document.getElementById('blocked-users-search')
|
const SearchBar = document.getElementById('blocked-users-search');
|
||||||
let ConfirmBtn = document.getElementById('blocked-users-confirm')
|
|
||||||
|
|
||||||
ConfirmBtn.addEventListener('click', function(){
|
SearchBar.addEventListener('input', function () {
|
||||||
SearchBlockedUsers(SearchBar.value);
|
SearchBlockedUsers(SearchBar.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
function SearchBlockedUsers(query) {
|
function SearchBlockedUsers(query) {
|
||||||
query = query.toLowerCase();
|
query = query.toLowerCase();
|
||||||
for (let i = 1; i < BlockedUsersCard.children.length; i++) {
|
for (let i = 1; i < BlockedUsersCard.children.length; i++) {
|
||||||
let Username = BlockedUsersCard.children[i].getElementsByTagName('h5')[0].innerText.toLowerCase();
|
let Username = BlockedUsersCard.children[i].getElementsByTagName('h5')[0].innerText.toLowerCase();
|
||||||
if (Username.includes(query)) {
|
if (Username.includes(query)) {
|
||||||
BlockedUsersCard.children[i].style.display = 'block'
|
BlockedUsersCard.children[i].style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
BlockedUsersCard.children[i].style.display = 'none'
|
BlockedUsersCard.children[i].style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
105
js/account/trade-valuation.js
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
var Settings;
|
||||||
|
var Utilities;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default;
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){
|
||||||
|
Settings = result.PolyPlus_Settings
|
||||||
|
if (
|
||||||
|
Settings.ValueListInfo &&
|
||||||
|
Settings.ValueListInfo.Enabled == true &&
|
||||||
|
Settings.ValueListInfo.TradeValuation == true
|
||||||
|
) {
|
||||||
|
const ColumnLabels = [
|
||||||
|
"name",
|
||||||
|
"short",
|
||||||
|
"value",
|
||||||
|
"type",
|
||||||
|
"trend",
|
||||||
|
"demand",
|
||||||
|
"tags"
|
||||||
|
]
|
||||||
|
|
||||||
|
const TagColors = {
|
||||||
|
"Projected": "warning",
|
||||||
|
"Hoarded": "success",
|
||||||
|
"Rare": "primary",
|
||||||
|
"Freaky": "danger"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Table to JSON function (slightly modified for my use-case)
|
||||||
|
https://stackoverflow.com/questions/9927126/how-to-convert-the-following-table-to-json-with-javascript#answer-60196347
|
||||||
|
*/
|
||||||
|
const ExtractTableJSON = function(table) {
|
||||||
|
var data = [];
|
||||||
|
for (var i = 1; i < table.rows.length; i++) {
|
||||||
|
var tableRow = table.rows[i];
|
||||||
|
var rowData = {
|
||||||
|
tags: []
|
||||||
|
};
|
||||||
|
for (var j = 0; j < tableRow.cells.length; j++) {
|
||||||
|
let Value = tableRow.cells[j].children[0].children[0].innerText;
|
||||||
|
if (ColumnLabels[j] === "name") {
|
||||||
|
const LinkValue = tableRow.cells[j].getElementsByTagName('a')[0]
|
||||||
|
if (LinkValue) {
|
||||||
|
rowData.id = LinkValue.href.split('https://www.google.com/url?q=')[1].split('&')[0].split('/')[4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ColumnLabels[j] === "tags") {
|
||||||
|
Array.from(tableRow.cells[j].children).forEach(tag => {
|
||||||
|
/*
|
||||||
|
The regex for the emoji character codes replacement was made by AI, such a time saver lol
|
||||||
|
*/
|
||||||
|
rowData.tags.push(tag.children[0].innerHTML.replace(/\s/g,'').replace(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, ''))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
rowData[ColumnLabels[j]] = Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.push(rowData);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ValueListDocument = new DOMParser().parseFromString(await (await fetch('https://docs.google.com/feeds/download/documents/Export?exportFormat=html&format=html&id=1W7JN74MU-9Dbd-9xNnjxE18hQVBPXWuwjK5DGSnuQR4')).text(), 'text/html')
|
||||||
|
|
||||||
|
const GetTagColor = function(label) {
|
||||||
|
if (TagColors[label] !== undefined) {
|
||||||
|
return TagColors[label]
|
||||||
|
} else if (TagColors[label.substring(1)] !== undefined) {
|
||||||
|
return TagColors[label.substring(1)]
|
||||||
|
} else {
|
||||||
|
return 'dark'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ValueJSON = ExtractTableJSON(ValueListDocument.getElementsByTagName('table')[0])
|
||||||
|
|
||||||
|
for (let card of Array.from(document.querySelectorAll('.card:has(a[href^="/store"])'))) {
|
||||||
|
const ItemValuations = Array.from(card.querySelectorAll('a[href^="/store"]')).map((item) => ValueJSON.filter((x) => x.id == item.getAttribute('href').split('/')[2])[0]||null).filter((x)=>x!=null)
|
||||||
|
|
||||||
|
if (ItemValuations.length > 0) {
|
||||||
|
/* this code is so bad I never want to look at it again */
|
||||||
|
|
||||||
|
const QuestionMarkTooltip = document.createElement('i')
|
||||||
|
QuestionMarkTooltip.classList = 'fa fa-question-circle'
|
||||||
|
QuestionMarkTooltip.setAttribute('data-bs-toggle', 'tooltip')
|
||||||
|
QuestionMarkTooltip.setAttribute('data-bs-html', 'true')
|
||||||
|
QuestionMarkTooltip.setAttribute('data-bs-title', ItemValuations.map((item, i) => `
|
||||||
|
<small class="text-muted" style="font-size: 0.65rem">"${item.short}" | ${item.trend}</small><br>
|
||||||
|
<b style="text-align: left !important;">${item.name}</b><br>
|
||||||
|
${ item.tags.map((x) => `
|
||||||
|
<span class="badge bg-${ GetTagColor(x) }">${x}</span>
|
||||||
|
`).join('')}
|
||||||
|
`).join('<hr class="mt-2 mb-1">'))
|
||||||
|
card.getElementsByClassName('card-header')[0].appendChild(QuestionMarkTooltip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Utilities.InjectResource("registerTooltips")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
@ -1,110 +1,108 @@
|
||||||
setTimeout(function() {}, 100)
|
var SelectedTrades = [];
|
||||||
var SelectedTrades = []
|
|
||||||
|
|
||||||
let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement
|
let Parent = document.getElementsByClassName('card mcard p-5 text-center text-muted')[0].parentElement;
|
||||||
let Text = document.createElement('p')
|
let Text = document.createElement('p');
|
||||||
Text.classList = 'mx-auto'
|
Text.classList = 'mx-auto';
|
||||||
Text.style.textAlign = 'center'
|
Text.style.textAlign = 'center';
|
||||||
Text.style.fontSize = '1.3rem'
|
Text.style.fontSize = '1.3rem';
|
||||||
Text.innerHTML = `
|
Text.innerHTML = `
|
||||||
<span>0</span> trades selected!
|
<span>0</span> trades selected!
|
||||||
<br>
|
<br>
|
||||||
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
|
<button id="viewSelectionBtn" class="btn btn-primary">View Selection</button>
|
||||||
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
|
<button id="clearSelectionBtn" class="btn btn-warning">Clear Selection</button>
|
||||||
<button id="cancelSelectionBtn" class="btn btn-danger">Cancel Selected Trades</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_Span = Text.querySelector('span');
|
||||||
let Text_View = document.getElementById('viewSelectionBtn');
|
let Text_View = document.getElementById('viewSelectionBtn');
|
||||||
let Text_Clear = document.getElementById('clearSelectionBtn');
|
let Text_Clear = document.getElementById('clearSelectionBtn');
|
||||||
let Text_Cancel = document.getElementById('cancelSelectionBtn');
|
let Text_Cancel = document.getElementById('cancelSelectionBtn');
|
||||||
|
|
||||||
var ConfirmCancel = 0
|
var ConfirmCancel = 0;
|
||||||
Text_View.addEventListener('click', function(){});
|
Text_View.addEventListener('click', function () {});
|
||||||
Text_Clear.addEventListener('click', function(){
|
Text_Clear.addEventListener('click', function () {
|
||||||
SelectedTrades = []
|
SelectedTrades = [];
|
||||||
UpdateCheckboxes();
|
UpdateCheckboxes();
|
||||||
Text_Span.innerText = SelectedTrades.length
|
Text_Span.innerText = SelectedTrades.length;
|
||||||
});
|
});
|
||||||
Text_Cancel.addEventListener('click', function(){
|
Text_Cancel.addEventListener('click', function () {
|
||||||
ConfirmCancel = ConfirmCancel + 1
|
ConfirmCancel = ConfirmCancel + 1;
|
||||||
switch(ConfirmCancel) {
|
switch (ConfirmCancel) {
|
||||||
case 0:
|
case 0:
|
||||||
Text_Cancel.innerText = 'Cancel Selected Trades'
|
Text_Cancel.innerText = 'Cancel Selected Trades';
|
||||||
break
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Text_Cancel.innerText = 'Are you sure?'
|
Text_Cancel.innerText = 'Are you sure?';
|
||||||
break
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
let Success = true
|
let Success = true;
|
||||||
for (let i = 0; i < SelectedTrades.length; i++) {
|
for (let i = 0; i < SelectedTrades.length; i++) {
|
||||||
setTimeout(function () {}, 110)
|
setTimeout(function () {}, 110);
|
||||||
console.log(SelectedTrades[i])
|
console.log(SelectedTrades[i]);
|
||||||
fetch('https://polytoria.com/api/trade/decline', {
|
fetch('https://polytoria.com/api/trade/decline', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ id: SelectedTrades[i] }),
|
body: JSON.stringify({id: SelectedTrades[i]})
|
||||||
})
|
}).catch((error) => {
|
||||||
.catch(error => {
|
// Handle any errors
|
||||||
// Handle any errors
|
console.error('Error:', error);
|
||||||
console.error('Error:', error);
|
Success = false;
|
||||||
Success = false
|
});
|
||||||
});
|
}
|
||||||
}
|
SelectedTrades = [];
|
||||||
SelectedTrades = []
|
UpdateCheckboxes();
|
||||||
UpdateCheckboxes();
|
Text_Cancel.innerText = 'Cancel Selected Trades';
|
||||||
Text_Cancel.innerText = 'Cancel Selected Trades'
|
ConfirmCancel = 0;
|
||||||
ConfirmCancel = 0
|
break;
|
||||||
break
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
LoadCheckBoxes();
|
LoadCheckBoxes();
|
||||||
|
|
||||||
function LoadCheckBoxes() {
|
function LoadCheckBoxes() {
|
||||||
Array.from(document.getElementsByClassName('card-inbox')).forEach(element => {
|
Array.from(document.getElementsByClassName('card-inbox')).forEach((element) => {
|
||||||
let ViewBtn = element.querySelector('a.btn.btn-primary')
|
let ViewBtn = element.querySelector('a.btn.btn-primary');
|
||||||
let TradeID = parseInt(ViewBtn.getAttribute('href').split('/')[3])
|
let TradeID = parseInt(ViewBtn.getAttribute('href').split('/')[3]);
|
||||||
var NewCheckBox = document.createElement('button')
|
var NewCheckBox = document.createElement('button');
|
||||||
NewCheckBox.classList = 'polyplus-multicanceltr-checkbox'
|
NewCheckBox.classList = 'polyplus-multicanceltr-checkbox';
|
||||||
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem; margin-left: 10px;')
|
NewCheckBox.setAttribute('style', 'padding: 20px; background-color: #191919; border: 1px solid #393939; border-radius: 1rem; margin-left: 10px;');
|
||||||
var Index = SelectedTrades.indexOf(TradeID)
|
var Index = SelectedTrades.indexOf(TradeID);
|
||||||
if (Index !== -1) {
|
if (Index !== -1) {
|
||||||
NewCheckBox.style.borderColor = 'lime'
|
NewCheckBox.style.borderColor = 'lime';
|
||||||
}
|
}
|
||||||
ViewBtn.parentElement.appendChild(NewCheckBox)
|
ViewBtn.parentElement.appendChild(NewCheckBox);
|
||||||
NewCheckBox.addEventListener('click', function(){
|
NewCheckBox.addEventListener('click', function () {
|
||||||
var Index = SelectedTrades.indexOf(TradeID)
|
var Index = SelectedTrades.indexOf(TradeID);
|
||||||
if (Index === -1) {
|
if (Index === -1) {
|
||||||
SelectedTrades.push(TradeID)
|
SelectedTrades.push(TradeID);
|
||||||
NewCheckBox.style.borderColor = 'lime'
|
NewCheckBox.style.borderColor = 'lime';
|
||||||
} else {
|
} else {
|
||||||
SelectedTrades.splice(Index, 1)
|
SelectedTrades.splice(Index, 1);
|
||||||
NewCheckBox.style.borderColor = '#393939'
|
NewCheckBox.style.borderColor = '#393939';
|
||||||
}
|
}
|
||||||
Text_Span.innerText = SelectedTrades.length
|
Text_Span.innerText = SelectedTrades.length;
|
||||||
UpdateCheckboxes();
|
UpdateCheckboxes();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function UpdateCheckboxes(){
|
function UpdateCheckboxes() {
|
||||||
document.querySelectorAll('.polyplus-multicanceltr-checkbox').forEach(element => {
|
document.querySelectorAll('.polyplus-multicanceltr-checkbox').forEach((element) => {
|
||||||
let Parent = element.parentElement
|
let Parent = element.parentElement;
|
||||||
let ViewBtn = Parent.querySelector('a.btn.btn-primary')
|
let ViewBtn = Parent.querySelector('a.btn.btn-primary');
|
||||||
if (element.getAttribute('disabled')) {
|
if (element.getAttribute('disabled')) {
|
||||||
element.removeAttribute('disabled')
|
element.removeAttribute('disabled');
|
||||||
}
|
}
|
||||||
if (SelectedTrades.IndexOf(ViewBtn.getAttribute('data-user-id')) === -1) {
|
if (SelectedTrades.IndexOf(ViewBtn.getAttribute('data-user-id')) === -1) {
|
||||||
element.style.borderColor = '#393939'
|
element.style.borderColor = '#393939';
|
||||||
} else {
|
} else {
|
||||||
element.style.borderColor = 'lime'
|
element.style.borderColor = 'lime';
|
||||||
if (SelectedTrades.length >= 10) {
|
if (SelectedTrades.length >= 10) {
|
||||||
element.setAttribute('disabled', true)
|
element.setAttribute('disabled', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
setTimeout(function () {}, 100)
|
/*
|
||||||
|
|
||||||
let Currencies;
|
let Currencies;
|
||||||
|
|
||||||
LoadFile(chrome.runtime.getURL('js/resources/currencies.json'), function(text){
|
LoadFile(chrome.runtime.getURL('resources/currencies.json'), function(text){
|
||||||
Currencies = JSON.parse(text)
|
Currencies = JSON.parse(text)
|
||||||
console.log(new Date(Currencies.Date).toLocaleDateString("en-US", {day:"numeric",month:"long",year:"numeric"}), Currencies)
|
console.log(new Date(Currencies.Date).toLocaleDateString("en-US", {day:"numeric",month:"long",year:"numeric"}), Currencies)
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
let Nav = document.querySelector('.nav-pills')
|
let Utilities;
|
||||||
let DIV = document.createElement('div')
|
(async () => {
|
||||||
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default;
|
||||||
|
})();
|
||||||
|
|
||||||
|
let Nav = document.getElementsByClassName('nav-pills')[0];
|
||||||
|
let DIV = document.createElement('div');
|
||||||
DIV.innerHTML = `
|
DIV.innerHTML = `
|
||||||
<input id="polyplus-brickconverter-input" type="number" class="form-control bg-dark mb-2" placeholder="How many Bricks?">
|
<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>
|
<input id="polyplus-brickconverter-output" type="text" class="form-control bg-dark mb-2" placeholder="Result" disabled>
|
||||||
|
|
@ -21,6 +27,7 @@ DIV.innerHTML = `
|
||||||
<option value="AUD">Australian Dollar (AUD)</option>
|
<option value="AUD">Australian Dollar (AUD)</option>
|
||||||
<option value="TRY">Turkish Lira (TRY)</option>
|
<option value="TRY">Turkish Lira (TRY)</option>
|
||||||
</select>
|
</select>
|
||||||
|
<!--
|
||||||
<select id="polyplus-brickconverter-package" class="form-select bg-dark">
|
<select id="polyplus-brickconverter-package" class="form-select bg-dark">
|
||||||
<option value="0" selected>$0.99 USD</option>
|
<option value="0" selected>$0.99 USD</option>
|
||||||
<option value="1">$4.99 USD</option>
|
<option value="1">$4.99 USD</option>
|
||||||
|
|
@ -29,73 +36,47 @@ DIV.innerHTML = `
|
||||||
<option value="4">c</option>
|
<option value="4">c</option>
|
||||||
<option value="5">d</option>
|
<option value="5">d</option>
|
||||||
</select>
|
</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 Input = document.getElementById('polyplus-brickconverter-input');
|
||||||
let Output = document.getElementById('polyplus-brickconverter-output')
|
let Output = document.getElementById('polyplus-brickconverter-output');
|
||||||
let Type = document.getElementById('polyplus-brickconverter-type')
|
let Type = document.getElementById('polyplus-brickconverter-type');
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
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')
|
//let Package = document.getElementById('polyplus-brickconverter-package')
|
||||||
|
|
||||||
Input.addEventListener('change', function(){
|
Input.addEventListener('input', function () {
|
||||||
Update()
|
Update();
|
||||||
});
|
});
|
||||||
|
|
||||||
Type.addEventListener('change', function(){
|
Type.addEventListener('change', function () {
|
||||||
Update()
|
Update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
Package.addEventListener('change', function(){
|
Package.addEventListener('change', function(){
|
||||||
Update()
|
Update()
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
function Update(){
|
async function Update() {
|
||||||
let DISPLAY = Type.options[Type.selectedIndex].value
|
if (Input.value === '') {
|
||||||
let IRL = (parseInt(Input.value.replace(/,/g, '')) * Currencies.Data[Package.selectedIndex][DISPLAY]).toFixed(2)
|
Output.value = '';
|
||||||
/*
|
return;
|
||||||
var IRL;
|
}
|
||||||
var DISPLAY;
|
const IRLResult = await Utilities.CalculateIRL(Input.value, Type.selectedIndex);
|
||||||
switch (Type.selectedIndex) {
|
Output.value = '$' + IRLResult.result + ' ' + IRLResult.display;
|
||||||
case 0:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.0099).toFixed(2)
|
|
||||||
DISPLAY = 'USD'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.009).toFixed(2)
|
|
||||||
DISPLAY = 'EUR'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.0131).toFixed(2)
|
|
||||||
DISPLAY = 'CAD'
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.0077).toFixed(2)
|
|
||||||
DISPLAY = 'GBP'
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.1691).toFixed(2)
|
|
||||||
DISPLAY = 'MXN'
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.0144).toFixed(2)
|
|
||||||
DISPLAY = 'AUD'
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
IRL = (parseInt(Input.value.replace(/,/g, '')) * 0.2338).toFixed(2)
|
|
||||||
DISPLAY = 'TRY'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Output.value = "$" + IRL + " " + DISPLAY
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadFile(path, callback) {
|
function LoadFile(path, callback) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.onload = function () { return callback(this.responseText); }
|
xhr.onload = function () {
|
||||||
xhr.open("GET", path, true);
|
return callback(this.responseText);
|
||||||
xhr.send();
|
};
|
||||||
|
xhr.open('GET', path, true);
|
||||||
|
xhr.send();
|
||||||
}
|
}
|
||||||
738
js/background.js
|
|
@ -1,133 +1,639 @@
|
||||||
const Manifest = chrome.runtime.getManifest()
|
const Manifest = chrome.runtime.getManifest();
|
||||||
|
const SettingsURL = chrome.runtime.getURL('settings.html');
|
||||||
|
|
||||||
|
const DefaultSettings = {
|
||||||
|
PinnedGamesOn: true,
|
||||||
|
ForumMentsOn: true,
|
||||||
|
BestFriendsOn: false,
|
||||||
|
ImprovedFrListsOn: false,
|
||||||
|
IRLPriceWithCurrency: {
|
||||||
|
Enabled: true,
|
||||||
|
Currency: 0,
|
||||||
|
Package: 0
|
||||||
|
},
|
||||||
|
IRLPriceWithCurrencyOn: true,
|
||||||
|
IRLPriceWithCurrencyCurrency: 0,
|
||||||
|
IRLPriceWithCurrencyPackage: 0,
|
||||||
|
HideNotifBadgesOn: false,
|
||||||
|
StoreOwnTagOn: true,
|
||||||
|
ThemeCreatorOn: false,
|
||||||
|
ThemeCreator: {
|
||||||
|
Enabled: false,
|
||||||
|
BGColor: null,
|
||||||
|
BGImage: null,
|
||||||
|
BGImageSize: 'fit',
|
||||||
|
PrimaryTextColor: null,
|
||||||
|
SecondaryTextColor: null,
|
||||||
|
LinkTextColor: null,
|
||||||
|
WebsiteLogo: null
|
||||||
|
},
|
||||||
|
ModifyNavOn: false,
|
||||||
|
ModifyNav: [
|
||||||
|
{
|
||||||
|
Label: 'Places',
|
||||||
|
Link: 'https://polytoria.com/places'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Store',
|
||||||
|
Link: 'https://polytoria.com/store'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Guilds',
|
||||||
|
Link: 'https://polytoria.com/guilds'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'People',
|
||||||
|
Link: 'https://polytoria.com/users'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Forum',
|
||||||
|
Link: 'https://polytoria.com/forum'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
MoreSearchFiltersOn: true,
|
||||||
|
ApplyMembershipTheme: {
|
||||||
|
Enabled: false,
|
||||||
|
Theme: 0
|
||||||
|
},
|
||||||
|
ApplyMembershipThemeOn: false,
|
||||||
|
ApplyMembershipThemeTheme: 0,
|
||||||
|
MultiCancelOutTradesOn: true,
|
||||||
|
ItemWishlistOn: true,
|
||||||
|
HideUpgradeBtnOn: false,
|
||||||
|
TryOnItemsOn: true,
|
||||||
|
OutfitCostOn: true,
|
||||||
|
ShowPlaceRevenueOn: true,
|
||||||
|
ReplaceItemSalesOn: false,
|
||||||
|
HoardersListOn: true,
|
||||||
|
HoardersList: {
|
||||||
|
Enabled: true,
|
||||||
|
AvatarsEnabled: false,
|
||||||
|
MinCopies: 2
|
||||||
|
},
|
||||||
|
LibraryDownloadsOn: true,
|
||||||
|
EventItemsCatOn: true,
|
||||||
|
HomeFriendCountOn: true,
|
||||||
|
HideUserAds: {
|
||||||
|
Enabled: false,
|
||||||
|
Banners: true,
|
||||||
|
Rectangles: true
|
||||||
|
},
|
||||||
|
UploadMultipleDecals: true,
|
||||||
|
GD_ServerBalanceOn: true,
|
||||||
|
AvatarDimensionToggleOn: true,
|
||||||
|
TheGreatDivide: {
|
||||||
|
Enabled: true,
|
||||||
|
UnbalancedIndicatorOn: true,
|
||||||
|
MVPUserIndicatorOn: true,
|
||||||
|
UserStatsOn: true,
|
||||||
|
LeaderboardsOn: true
|
||||||
|
},
|
||||||
|
CollectibleInventoryCatOn: true,
|
||||||
|
ValueListInfo: {
|
||||||
|
Enabled: true,
|
||||||
|
ItemValuation: true,
|
||||||
|
TradeValuation: true
|
||||||
|
},
|
||||||
|
ImprovedAchievements: {
|
||||||
|
Enabled: true,
|
||||||
|
ProgressBarOn: true,
|
||||||
|
PercentageOn: true,
|
||||||
|
OpacityOn: true
|
||||||
|
},
|
||||||
|
ReaddCopyablePlacesOn: true,
|
||||||
|
TimePlayedOn: true,
|
||||||
|
HomeJoinFriendsButtonOn: true,
|
||||||
|
ImprovedPlaceManagement: {
|
||||||
|
Enabled: true,
|
||||||
|
QuickActivityToggleOn: true,
|
||||||
|
PlaceFileDownloadOn: true,
|
||||||
|
MultiWhitelistOn: true,
|
||||||
|
ClearWhitelistOn: true
|
||||||
|
},
|
||||||
|
MoreBlockedDetailsOn: true,
|
||||||
|
AssetDesignerCreditOn: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ON EXTENSION INSTALL / RELOAD
|
||||||
|
chrome.runtime.onInstalled.addListener(() => {
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
||||||
|
const MergedSettings = MergeObjects((result.PolyPlus_Settings || DefaultSettings), DefaultSettings)
|
||||||
|
chrome.storage.sync.set({'PolyPlus_Settings': MergedSettings}, function(){
|
||||||
|
console.log('Successfully merged settings')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let RecordingTimePlayed = false
|
||||||
|
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||||
|
if (request.action === 'reload') {
|
||||||
|
chrome.runtime.reload();
|
||||||
|
} else if (request.action === 'greatdivide_stats') {
|
||||||
|
chrome.storage.local.get(['PolyPlus_GreatDivideStats'], async function(result){
|
||||||
|
const Cache = (result['PolyPlus_GreatDivideStats']||{[request.userID]:undefined})
|
||||||
|
|
||||||
|
// cache for 5 minutes
|
||||||
|
if (Cache[request.userID] === undefined || (new Date().getTime() - Cache[request.userID].requested > 300000)) {
|
||||||
|
let Statistics = (await (await fetch('https://stats.silly.mom/player_stats?id=' + request.userID)).json()).results
|
||||||
|
if (Statistics !== null) {
|
||||||
|
Statistics = Statistics[0]
|
||||||
|
}
|
||||||
|
Cache[request.userID] = {
|
||||||
|
data: Statistics,
|
||||||
|
requested: new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.storage.local.set({['PolyPlus_GreatDivideStats']: Cache}, function(){})
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs){
|
||||||
|
chrome.scripting
|
||||||
|
.executeScript({
|
||||||
|
target: {tabId: tabs[0].id},
|
||||||
|
func: LoadStats,
|
||||||
|
args: [Cache[request.userID].data]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const LoadStats = function(stats){
|
||||||
|
const GreatDivideCard = document.getElementById('p+greatdivide_card')
|
||||||
|
if (stats !== null) {
|
||||||
|
let KDR = (stats.Kills / stats.Deaths)
|
||||||
|
if (isNaN(KDR)) {
|
||||||
|
KDR = "N/A"
|
||||||
|
} else {
|
||||||
|
KDR = KDR.toFixed(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.Team === 'phantoms') {
|
||||||
|
GreatDivideCard.parentElement.style.backgroundImage = 'linear-gradient(rgba(0.7, 0.7, 0.7, 0.7), rgba(0.7, 0.7, 0.7, 0.7)), url("https://c0.ptacdn.com/assets/N3DH4x5a6iW7raaQ-3lwHpRHHpWShdXc.png")';
|
||||||
|
GreatDivideCard.parentElement.style.borderColor = '';
|
||||||
|
GreatDivideCard.parentElement.style.border = '1.25px solid blue !important';
|
||||||
|
} else {
|
||||||
|
GreatDivideCard.parentElement.style.backgroundImage = 'linear-gradient(rgba(0.7, 0.7, 0.7, 0.7), rgba(0.7, 0.7, 0.7, 0.7)), url("https://c0.ptacdn.com/assets/1HXpaoDLHJo2rrvwwxqJEDWvDZ6BgvSE.png")';
|
||||||
|
GreatDivideCard.parentElement.style.borderColor = '';
|
||||||
|
GreatDivideCard.parentElement.style.border = '1.25px solid green !important';
|
||||||
|
}
|
||||||
|
|
||||||
|
GreatDivideCard.innerHTML = `
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-eye text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Last Round Seen
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${ (stats.LastRoundSeen === 0) ? '-' : stats.LastRoundSeen }
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-3 mt-2">
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-swords text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Kills
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.Kills.toLocaleString()} <small class="text-muted" style="font-size: 0.8rem;">(${stats.UniqueKills.toLocaleString()} unique)</small>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-skull text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Deaths
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.Deaths.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-solid fa-percent text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Kill Death Ratio
|
||||||
|
</b>
|
||||||
|
<span class="float-end ${ (!isNaN(KDR) && KDR > 1) ? 'text-success' : (!isNaN(KDR) && KDR !== 0) ? 'text-danger' : '' }">
|
||||||
|
${KDR} <i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-title="KDR is a user's kills divided by the amount of times they have died. If their KDR is above 1, they are making a positive contribution. If their KDR is less than 1, that means they die more than they kill."></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-hundred-points text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Points Scored
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.PointsScored.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-solid fa-money-bill-wave text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Cash Earned
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.CashEarned.toLocaleString()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-flag text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Flags Captured
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.FlagsCaptured} (${stats.FlagsReturned} returned)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<b>
|
||||||
|
<i class="fa-solid fa-box-open text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Airdrops Collected
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.AirdropsCollected}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-3 mt-2">
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-solid fa-chart-pyramid text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Monoliths Destroyed
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.ObelisksDestroyed}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-block-question text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Blocks Placed
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.BlocksPlaced} (${stats.BlocksDestroyed} destroyed)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-head-side-brain text-center d-inline-block" style="width:1.2em"></i>
|
||||||
|
Headshots
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${stats.Headshots}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
const Script = document.createElement('script');
|
||||||
|
Script.setAttribute('type', 'text/javascript');
|
||||||
|
Script.setAttribute('src', chrome.runtime.getURL('resources/registerTooltips.js'));
|
||||||
|
Script.addEventListener('load', function () {
|
||||||
|
Script.remove();
|
||||||
|
});
|
||||||
|
document.body.appendChild(Script);
|
||||||
|
} else {
|
||||||
|
GreatDivideCard.classList.add('text-center', 'py-5')
|
||||||
|
GreatDivideCard.innerHTML = `
|
||||||
|
<h1 class="display-3"><i class="fa-solid fa-face-thinking"></i></h1>
|
||||||
|
<h5> Not Drafted </h5>
|
||||||
|
<p class="mb-0">This user didn't participate in The Great Divide.</p>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
} else if (request.action === 'start_time_played') {
|
||||||
|
if (RecordingTimePlayed === true) {
|
||||||
|
console.log('Time Played: Already Started Interval')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
RecordingTimePlayed = true
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_TimePlayed'], function(result){
|
||||||
|
console.log('Time Played: Start Interval')
|
||||||
|
|
||||||
|
const Playtime = result.PolyPlus_TimePlayed || {
|
||||||
|
[request.placeID]: 0
|
||||||
|
};
|
||||||
|
let LoadedIn = false
|
||||||
|
const TimePlayedInterval = setInterval(async () => {
|
||||||
|
console.log('Time Played: Run Check')
|
||||||
|
const PlaceStatus = (await (await fetch('https://api.polytoria.com/v1/users/' + request.userID)).json()).playing
|
||||||
|
|
||||||
|
if (PlaceStatus === null) {
|
||||||
|
console.log('Time Played: Not Playing Anything')
|
||||||
|
if (LoadedIn === true) {
|
||||||
|
console.log('Time Played: End Interval')
|
||||||
|
clearInterval(TimePlayedInterval)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LoadedIn = true
|
||||||
|
if (!Playtime[PlaceStatus.placeID]) {
|
||||||
|
Playtime[PlaceStatus.placeID] = 0
|
||||||
|
}
|
||||||
|
Playtime[PlaceStatus.placeID] += 5
|
||||||
|
console.log('Time Played: Time Increase: ', new Date(Playtime[PlaceStatus.placeID] * 1000).toISOString().slice(11, 19), PlaceStatus)
|
||||||
|
chrome.storage.sync.set({'PolyPlus_TimePlayed': Playtime}, function(){
|
||||||
|
console.log('Time Played: Saved Playtime')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
})
|
||||||
|
} else if (request.action == "item_valuation") {
|
||||||
|
chrome.storage.local.get(['PolyPlus_ItemValuationData'], async function(result){
|
||||||
|
const Cache = (result['PolyPlus_ItemValuationData']||{[request.itemID]:undefined})
|
||||||
|
|
||||||
|
// cache for 5 minutes
|
||||||
|
if (Cache[request.itemID] === undefined || (new Date().getTime() - Cache[request.itemID].requested > 300000)) {
|
||||||
|
let ValueDetails = (await (await fetch('https://polytoria.trade/api/trpc/getItem?batch=1&input={"0":' + request.itemID + '}',{mode:'no-cors'})).json())
|
||||||
|
if (ValueDetails.result.length > 0) {
|
||||||
|
ValueDetails = ValueDetails[0].result.data
|
||||||
|
}
|
||||||
|
Cache[request.itemID] = {
|
||||||
|
data: ValueDetails,
|
||||||
|
requested: new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.storage.local.set({['PolyPlus_GreatDivideStats']: Cache}, function(){})
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs){
|
||||||
|
chrome.scripting
|
||||||
|
.executeScript({
|
||||||
|
target: {tabId: tabs[0].id},
|
||||||
|
func: LoadValuation,
|
||||||
|
args: [Cache[request.itemID].data]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const LoadValuation = async function(valuation) {
|
||||||
|
const GetTagColor = function(label) {
|
||||||
|
if (TagColors[label] !== undefined) {
|
||||||
|
return TagColors[label]
|
||||||
|
} else if (TagColors[label.substring(1)] !== undefined) {
|
||||||
|
return TagColors[label.substring(1)]
|
||||||
|
} else {
|
||||||
|
return 'dark'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TagColors = {
|
||||||
|
"Projected": "warning",
|
||||||
|
"Hoarded": "success",
|
||||||
|
"Rare": "primary",
|
||||||
|
"Freaky": "danger"
|
||||||
|
}
|
||||||
|
|
||||||
|
//const ValueDetails = (await (await fetch('https://polytoria.trade/api/trpc/getItem?batch=1&input={"0":' + ItemID + '}')).json())
|
||||||
|
|
||||||
|
if (valuation !== undefined) {
|
||||||
|
ValueCard.innerHTML = `
|
||||||
|
<div class="mb-1">
|
||||||
|
<b class="text-success">
|
||||||
|
<i class="pi pi-brick" style="width:1.2em"></i>
|
||||||
|
Value
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${valuation.value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b class="text-primary"">
|
||||||
|
<i class="pi" style="width:1.2em">%</i>
|
||||||
|
Trend
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${valuation.trend}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-triangle" style="width:1.2em"></i>
|
||||||
|
Valuation Type
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${valuation.type}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1">
|
||||||
|
<b>
|
||||||
|
<i class="fa-duotone fa-hand-wave" style="width:1.2em"></i>
|
||||||
|
Shorthand
|
||||||
|
</b>
|
||||||
|
<span class="float-end">
|
||||||
|
${valuation.short}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex" style="gap: 5px;">
|
||||||
|
${ ValueDetails.tags.map((x) => `
|
||||||
|
<span class="badge bg-${ GetTagColor(x) }">${x}</span>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
} else {
|
||||||
|
ValueCard.innerHTML = `
|
||||||
|
There is no evaluation for this item at this time.
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// WHEN CLICKING ON EXTENSION ICON OPEN THE SETTINGS PAGE
|
// WHEN CLICKING ON EXTENSION ICON OPEN THE SETTINGS PAGE
|
||||||
chrome.action.onClicked.addListener((tab) => {
|
chrome.action.onClicked.addListener((tab) => {
|
||||||
chrome.tabs.create({ active: true, url: chrome.runtime.getURL('settings.html') });
|
chrome.tabs.create({active: true, url: SettingsURL});
|
||||||
});
|
});
|
||||||
|
|
||||||
// REGISTER AN ALARM FOR DAILY UPDATE CHECK (chatgpt cause I'm lazy and have to release Poly+ on February 8th aka today at the time of writing this)
|
chrome.contextMenus.removeAll(function () {
|
||||||
// Calculate the milliseconds until the next 12 PM
|
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
|
||||||
/*
|
/*
|
||||||
const now = new Date();
|
const AssetTypes = ["Place", "User", "Item", "Guild"]
|
||||||
const msUntilNext12PM = new Date(
|
AssetTypes.forEach(type => {
|
||||||
now.getFullYear(),
|
chrome.contextMenus.create({
|
||||||
now.getMonth(),
|
title: 'Copy ' + type + ' ID',
|
||||||
now.getDate(),
|
id: 'PolyPlus-Copy' + type + 'ID',
|
||||||
12, // 12 PM hour
|
contexts: ['link'],
|
||||||
0, // 0 minutes
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
0 // 0 seconds
|
targetUrlPatterns: [
|
||||||
) - now;
|
'https://polytoria.com/places/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy Place ID',
|
||||||
|
id: 'PolyPlus-CopyPlaceID',
|
||||||
|
contexts: ['link'],
|
||||||
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
|
targetUrlPatterns: [
|
||||||
|
'https://polytoria.com/places/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy User ID',
|
||||||
|
id: 'PolyPlus-CopyUserID',
|
||||||
|
contexts: ['link'],
|
||||||
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
|
targetUrlPatterns: [
|
||||||
|
'https://polytoria.com/users/**',
|
||||||
|
'https://polytoria.com/u/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy Item ID',
|
||||||
|
id: 'PolyPlus-CopyItemID',
|
||||||
|
contexts: ['link'],
|
||||||
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
|
targetUrlPatterns: [
|
||||||
|
'https://polytoria.com/store/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy Guild ID',
|
||||||
|
id: 'PolyPlus-CopyGuildID',
|
||||||
|
contexts: ['link'],
|
||||||
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
|
targetUrlPatterns: [
|
||||||
|
'https://polytoria.com/guilds/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy Thread ID',
|
||||||
|
id: 'PolyPlus-CopyThreadID',
|
||||||
|
contexts: ['link'],
|
||||||
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
|
targetUrlPatterns: [
|
||||||
|
'https://polytoria.com/forum/post/**'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
// Convert milliseconds to minutes
|
// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION
|
||||||
const minutesUntilNext12PM = msUntilNext12PM / (1000 * 60);
|
chrome.contextMenus.create({
|
||||||
|
title: 'Copy Avatar Hash',
|
||||||
// Create the alarm
|
id: 'PolyPlus-CopyAvatarHash',
|
||||||
chrome.alarms.create("PolyPlus-UpdateCheck", {
|
contexts: ['image'],
|
||||||
periodInMinutes: 24 * 60, // 24 hours
|
documentUrlPatterns: ['https://polytoria.com/*', SettingsURL],
|
||||||
delayInMinutes: minutesUntilNext12PM, // Time until next 12 PM
|
targetUrlPatterns: [
|
||||||
});
|
'https://c0.ptacdn.com/thumbnails/avatars/**'
|
||||||
*/
|
]
|
||||||
|
});
|
||||||
// HANDLE ALARMS FIRING
|
|
||||||
chrome.alarms.onAlarm.addListener(function(alarm){
|
|
||||||
if (alarm.name === 'PolyPlus-UpdateCheck') {
|
|
||||||
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) {
|
|
||||||
console.log('Update available')
|
|
||||||
chrome.notifications.create("", {
|
|
||||||
type: "basic",
|
|
||||||
iconUrl: chrome.runtime.getURL("icon.png"),
|
|
||||||
title: "New Update Available",
|
|
||||||
message: "A new update is available for Poly+!",
|
|
||||||
}, function(notificationID) {
|
|
||||||
chrome.notifications.onClicked.addListener(function (id) {
|
|
||||||
if (id === notificationID) {
|
|
||||||
chrome.tabs.create({url: 'https://github.com/IndexingGitHub/PolyPlus', active: true})
|
|
||||||
chrome.notifications.clear(notificationID)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {console.log(error)})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
|
|
||||||
chrome.contextMenus.create({
|
|
||||||
title: 'Copy Asset ID',
|
|
||||||
id: 'PolyPlus-CopyID',
|
|
||||||
contexts: ['link'],
|
|
||||||
documentUrlPatterns: ['https://polytoria.com/*'],
|
|
||||||
targetUrlPatterns: [
|
|
||||||
"https://polytoria.com/places/**",
|
|
||||||
"https://polytoria.com/users/**",
|
|
||||||
"https://polytoria.com/store/**"
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION
|
|
||||||
chrome.contextMenus.create({
|
|
||||||
title: 'Copy Avatar Hash',
|
|
||||||
id: 'PolyPlus-CopyAvatarHash',
|
|
||||||
contexts: ['image'],
|
|
||||||
documentUrlPatterns: ['https://polytoria.com/*'],
|
|
||||||
targetUrlPatterns: [
|
|
||||||
"https://c0.ptacdn.com/thumbnails/avatars/**",
|
|
||||||
"https://c0.ptacdn.com/thumbnails/avatars/**"
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// HANDLE CONTEXT MENU ITEMS
|
// HANDLE CONTEXT MENU ITEMS
|
||||||
chrome.contextMenus.onClicked.addListener(function (info, tab){
|
chrome.contextMenus.onClicked.addListener(async function (info, tab) {
|
||||||
if (info.menuItemId === 'PolyPlus-CopyID') {
|
if (["CopyPlaceID", "CopyUserID", "CopyItemID", "CopyGuildID"].indexOf(info.menuItemId.split('-')[1]) !== -1) {
|
||||||
let ID = parseInt(info.linkUrl.split('/')[4])
|
let ID = info.linkUrl.split('/')[4];
|
||||||
chrome.scripting
|
if (info.linkUrl.split('/')[3] === 'u') {
|
||||||
.executeScript({
|
ID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + info.linkUrl.split('/')[4])).json()).id;
|
||||||
target: {tabId: tab.id},
|
}
|
||||||
func: CopyAssetID,
|
chrome.scripting
|
||||||
args: [ID]
|
.executeScript({
|
||||||
})
|
target: {tabId: tab.id},
|
||||||
.then(() => console.log("Copied ID!"));
|
func: CopyAssetID,
|
||||||
}
|
args: [ID]
|
||||||
|
})
|
||||||
|
.then(() => console.log('Copied ID!'));
|
||||||
|
}
|
||||||
|
|
||||||
if (info.menuItemId === 'PolyPlus-CopyAvatarHash') {
|
if (info.menuItemId === 'PolyPlus-CopyThreadID') {
|
||||||
let Hash = new URL(info.srcUrl).pathname.split('/')[3].replace('-icon', '').replace('.png', '')
|
let ID = info.linkUrl.split('/')[5];
|
||||||
chrome.scripting
|
chrome.scripting
|
||||||
.executeScript({
|
.executeScript({
|
||||||
target: {tabId: tab.id},
|
target: {tabId: tab.id},
|
||||||
func: CopyAvatarHash,
|
func: CopyAssetID,
|
||||||
args: [Hash]
|
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', '');
|
||||||
|
chrome.scripting
|
||||||
|
.executeScript({
|
||||||
|
target: {tabId: tab.id},
|
||||||
|
func: CopyAvatarHash,
|
||||||
|
args: [Hash]
|
||||||
|
})
|
||||||
|
.then(() => console.log('Copied ID!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.menuItemId === 'PolyPlus-RunUpdateNotifier') {
|
||||||
|
RunUpdateNotifier();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function CopyAssetID(id) {
|
/*
|
||||||
navigator.clipboard
|
GREEN LOGO WHEN EXTENSION APPLIES TO CURRENT TAB PAGE, RED WHEN IT DOESN'T
|
||||||
.writeText(id)
|
COMING SOON
|
||||||
.then(() => {
|
|
||||||
alert('Successfully copied ID!')
|
chrome.tabs.onActivated.addListener(function (info){
|
||||||
|
chrome.tabs.get(info.tabId, function(tab){
|
||||||
|
const Any = CheckIfScriptApplies(tab.url)
|
||||||
|
console.log(Any)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function CheckIfScriptApplies(url) {
|
||||||
|
const matches = Manifest.content_scripts.map(script => {
|
||||||
|
script.matches.forEach(match => {
|
||||||
|
console.log(url, match, url.startsWith(match))
|
||||||
|
if (url.startsWith(match)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
})
|
||||||
alert('Failure to copy ID.')
|
|
||||||
});
|
return matches
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesUrl(patterns, url) {
|
||||||
|
return patterns.some(pattern => {
|
||||||
|
return new RegExp(pattern).test(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function CopyAssetID(id) {
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(id)
|
||||||
|
.catch((err) => {
|
||||||
|
alert('Failure to copy ID.', err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function CopyAvatarHash(hash) {
|
function CopyAvatarHash(hash) {
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.writeText(hash)
|
.writeText(hash)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
alert('Successfully copied avatar hash!')
|
alert('Successfully copied avatar hash!');
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
alert('Failure to copy avatar hash.')
|
alert('Failure to copy avatar hash.');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function OpenSweetAlert2Modal(icon, title, text) {
|
||||||
|
console.log(window, window.Swal, window.bootstrap)
|
||||||
|
window.Swal.fire({
|
||||||
|
icon: icon,
|
||||||
|
title: title,
|
||||||
|
text: text
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergeObjects function was written by ChatGPT cause I was lazy and it was awhile ago
|
||||||
|
function MergeObjects(obj1, obj2) {
|
||||||
|
var mergedObj = {};
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
61
js/create/audio-library.js
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
const AssetGrid = document.getElementById('assets')
|
||||||
|
|
||||||
|
const AssetObserver = new MutationObserver(async function (list) {
|
||||||
|
const SelectedTab = document.getElementsByClassName('nav-link active')[0].getAttribute('data-category')
|
||||||
|
if (SelectedTab === "audio") {
|
||||||
|
for (const record of list) {
|
||||||
|
for (const audio of record.addedNodes) {
|
||||||
|
if (audio.tagName === 'DIV') {
|
||||||
|
const PlayButton = document.createElement('button')
|
||||||
|
PlayButton.classList = 'btn btn-primary btn-sm'
|
||||||
|
PlayButton.style = 'position: absolute; bottom: 0; right: 0; margin: 5px; margin-bottom: 55px; z-index: 2000;'
|
||||||
|
PlayButton.innerHTML = '<i class="fa-solid fa-play"></i>'
|
||||||
|
audio.getElementsByTagName('a')[0].parentElement.insertBefore(PlayButton, audio.getElementsByTagName('a')[0])
|
||||||
|
audio.children[0].style.position = 'relative'
|
||||||
|
|
||||||
|
let AudioElement = null
|
||||||
|
let Playing = false
|
||||||
|
PlayButton.addEventListener('click', async function(){
|
||||||
|
if (!Playing) {
|
||||||
|
if (AudioElement === null) {
|
||||||
|
PlayButton.innerHTML = '<div class="spinner-border text-light" role="status" style="--bs-spinner-width: 15px; --bs-spinner-height: 15px; --bs-spinner-border-width: 2px; vertical-align: middle; text-align: center;"><span class="sr-only">Loading...</span></div>'
|
||||||
|
const AudioURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-audio/' + audio.querySelector('a[href^="/store"]').getAttribute('href').split('/')[2])).json())
|
||||||
|
if (AudioURL.success) {
|
||||||
|
AudioElement = new Audio(AudioURL.url)
|
||||||
|
} else {
|
||||||
|
PlayButton.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioElement.addEventListener("canplaythrough", (event) => {
|
||||||
|
Playing = true
|
||||||
|
AudioElement.play();
|
||||||
|
PlayButton.innerHTML = '<i class="fa-duotone fa-solid fa-play-pause"></i>'
|
||||||
|
PlayButton.classList = 'btn btn-warning btn-sm'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Playing = true
|
||||||
|
AudioElement.play();
|
||||||
|
PlayButton.innerHTML = '<i class="fa-duotone fa-solid fa-play-pause"></i>'
|
||||||
|
PlayButton.classList = 'btn btn-warning btn-sm'
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioElement.addEventListener("ended", function() {
|
||||||
|
Playing = false
|
||||||
|
PlayButton.innerHTML = '<i class="fa-solid fa-play"></i>'
|
||||||
|
PlayButton.classList = 'btn btn-primary btn-sm'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Playing = false
|
||||||
|
AudioElement.pause()
|
||||||
|
PlayButton.innerHTML = '<i class="fa-solid fa-play"></i>'
|
||||||
|
PlayButton.classList = 'btn btn-primary btn-sm'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssetObserver.observe(AssetGrid, {attributes: false, childList: true, subtree: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AssetObserver.observe(AssetGrid, {attributes: false, childList: true, subtree: false});
|
||||||
85
js/create/image.js
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
credit to goldenretriveryt on Polytoria for making the multi-decal uploading feature
|
||||||
|
*/
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
var Settings = [];
|
||||||
|
chrome.storage.sync.get(["PolyPlus_Settings"], async function (result) {
|
||||||
|
let Utilities = (await import(chrome.runtime.getURL("resources/utils.js")))
|
||||||
|
.default;
|
||||||
|
Settings = result.PolyPlus_Settings || {
|
||||||
|
UploadMultipleDecals: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Settings.UploadMultipleDecals === true) {
|
||||||
|
UploadMultipleDecals();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function UploadMultipleDecals() {
|
||||||
|
const fileInput = document.querySelector("#file");
|
||||||
|
fileInput.setAttribute("multiple", "true");
|
||||||
|
|
||||||
|
const submitBtn = document.querySelector(
|
||||||
|
"form[action^=\"/create\"] button[type=\"submit\"]"
|
||||||
|
);
|
||||||
|
const nameInput = document.querySelector("form[action^=\"/create\"] input[name=\"name\"]")
|
||||||
|
console.log(submitBtn)
|
||||||
|
submitBtn.addEventListener("click", async function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.textContent =
|
||||||
|
"Uploading... (0/" + fileInput.files.length + ")";
|
||||||
|
const files = fileInput.files;
|
||||||
|
|
||||||
|
// we cant submit multiple files to the API, so we create a request for each file
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
const uploadFile = async (file, index) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
|
||||||
|
if (nameInput.value !== "") {
|
||||||
|
formData.append("name", nameInput.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await Utilities.RatelimitRepeatingFetch(
|
||||||
|
"https://polytoria.com/create/upload-decal",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
i++;
|
||||||
|
submitBtn.textContent =
|
||||||
|
"Uploading... (" + i + "/" + fileInput.files.length + ")";
|
||||||
|
} else {
|
||||||
|
throw new Error(response.status);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
submitBtn.textContent =
|
||||||
|
"File " + index + " failed to upload: " + err;
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
throw err; // re-throw the error to stop further processing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadFiles = async () => {
|
||||||
|
try {
|
||||||
|
await Promise.all(Array.from(files).map(uploadFile));
|
||||||
|
submitBtn.textContent = "Upload";
|
||||||
|
submitBtn.disabled = false;
|
||||||
|
window.location.reload();
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Some files failed to upload:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadFiles();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
264
js/create/place-access.js
Executable file
|
|
@ -0,0 +1,264 @@
|
||||||
|
const PlaceID = window.location.pathname.split('/')[3];
|
||||||
|
const Form = document.querySelector('form[action="/create/place/update"]');
|
||||||
|
|
||||||
|
var Settings;
|
||||||
|
var PlaceData = null;
|
||||||
|
|
||||||
|
let Utilities;
|
||||||
|
|
||||||
|
!(async () => {
|
||||||
|
Utilities = (await import(chrome.runtime.getURL('resources/utils.js')))
|
||||||
|
.default;
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
||||||
|
Settings = result.PolyPlus_Settings || Utilities.DefaultSettings;
|
||||||
|
|
||||||
|
if (Settings.ImprovedPlaceManagement.Enabled) {
|
||||||
|
if (Settings.ImprovedPlaceManagement.QuickActivityToggleOn && Settings.ImprovedPlaceManagement.QuickActivityToggleOn === true) {
|
||||||
|
ActivityToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedPlaceManagement.PlaceFileDownloadOn && Settings.ImprovedPlaceManagement.PlaceFileDownloadOn === true) {
|
||||||
|
CopyOwnedPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedPlaceManagement.MultiWhitelistOn && Settings.ImprovedPlaceManagement.MultiWhitelistOn === true) {
|
||||||
|
MultiWhitelist();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedPlaceManagement.ClearWhitelistOn && Settings.ImprovedPlaceManagement.ClearWhitelistOn === true) {
|
||||||
|
ClearWhitelist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})();
|
||||||
|
|
||||||
|
async function ActivityToggle() {
|
||||||
|
if (PlaceData === null) {
|
||||||
|
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID);
|
||||||
|
PlaceData = await PlaceData.json();
|
||||||
|
}
|
||||||
|
let Status = PlaceData.isActive;
|
||||||
|
|
||||||
|
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 <span id="p+current_place_activity">${Status === true ? 'active' : 'inactive'}</span>).</small>
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 = 'Set ' + (Status === true ? 'Private' : 'Public');
|
||||||
|
DIV.appendChild(ActivityBtn);
|
||||||
|
|
||||||
|
ActivityBtn.addEventListener('click', async function () {
|
||||||
|
const Toggle = (await (await fetch(`https://polytoria.com/api/places/${PlaceID}/toggle-active`,{ method: 'POST' })).json())
|
||||||
|
if (Toggle.success) {
|
||||||
|
Status = Toggle.isActive;
|
||||||
|
ActivityBtn.innerText = 'Set ' + (Status === true ? 'Private' : 'Public');
|
||||||
|
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success');
|
||||||
|
Status === true ? document.getElementById('p+current_place_activity').innerText = 'active' : document.getElementById('p+current_place_activity').innerText = 'inactive'
|
||||||
|
} else {
|
||||||
|
//chrome.runtime.sendMessage({ action: "sweetalert2", icon: "error", title: "Error", text: Toggle.message });
|
||||||
|
alert(Toggle.message)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function RequestGameProfile() {
|
||||||
|
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..">
|
||||||
|
<input type="color" class="form-control bg-dark mb-2" placeholder="Background Color..">
|
||||||
|
<input type="color" class="form-control bg-dark mb-2" placeholder="Accent Color..">
|
||||||
|
<input type="color" class="form-control bg-dark mb-2" placeholder="Secondary Color..">
|
||||||
|
<input type="color" class="form-control bg-dark mb-2" placeholder="Card Background Color..">
|
||||||
|
<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]);
|
||||||
|
|
||||||
|
const SubmitBtn = Div.getElementsByTagName('button')[0];
|
||||||
|
|
||||||
|
SubmitBtn.addEventListener('click', function () {
|
||||||
|
const CardBody = Div.children[0];
|
||||||
|
const Result = {
|
||||||
|
gameTitle: CardBody.children[0].value,
|
||||||
|
bg: CardBody.children[1].value,
|
||||||
|
accent: CardBody.children[2].value,
|
||||||
|
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)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function CopyOwnedPlace() {
|
||||||
|
if (PlaceData === null) {
|
||||||
|
PlaceData = await fetch('https://api.polytoria.com/v1/places/' + PlaceID);
|
||||||
|
PlaceData = await PlaceData.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlaceData.creator.id !== parseInt(JSON.parse(window.localStorage.getItem('p+account_info')).ID)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
<small class="text-muted">Quickly download your place from the site!</small>
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
<button type="button" class="btn btn-primary">Download</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
Form.insertBefore(DIV, Form.children[Form.children.length - 1]);
|
||||||
|
|
||||||
|
const DownloadButton = DIV.getElementsByTagName('button')[0];
|
||||||
|
DownloadButton.addEventListener('click', async function () {
|
||||||
|
let CreatorToken = await fetch('https://polytoria.com/api/places/edit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({placeID: PlaceID})
|
||||||
|
});
|
||||||
|
CreatorToken = await CreatorToken.json();
|
||||||
|
CreatorToken = CreatorToken.token;
|
||||||
|
|
||||||
|
fetch(`https://api.polytoria.com/v1/places/get-place?id=${PlaceID}&tokenType=creator`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: CreatorToken
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network not ok');
|
||||||
|
}
|
||||||
|
return response.blob();
|
||||||
|
})
|
||||||
|
.then((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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function MultiWhitelist(){
|
||||||
|
const WhitelistCard = document.querySelector('.card:has(#whitelist-username)')
|
||||||
|
|
||||||
|
const MultiWhitelistCard = document.createElement('card')
|
||||||
|
MultiWhitelistCard.classList = 'card mt-3'
|
||||||
|
MultiWhitelistCard.innerHTML = `
|
||||||
|
<div class="card-header">
|
||||||
|
<i class="fa-duotone fa-solid fa-vial-circle-check"></i>
|
||||||
|
Multi-Whitelist
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<textarea class="form-control bg-dark mb-2" placeholder="Usernames (separated by lines).." style="min-height: 250px;"></textarea>
|
||||||
|
<button class="btn btn-primary">
|
||||||
|
<i class="fa-duotone fa-solid fa-users"></i>
|
||||||
|
Whitelist
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
WhitelistCard.parentElement.appendChild(MultiWhitelistCard)
|
||||||
|
|
||||||
|
const MultiWhitelistSubmitButton = MultiWhitelistCard.getElementsByTagName('button')[0]
|
||||||
|
|
||||||
|
MultiWhitelistSubmitButton.addEventListener('click', async function(){
|
||||||
|
const Usernames = MultiWhitelistSubmitButton.previousElementSibling.value.split('\n').filter((x) => x !== "")
|
||||||
|
MultiWhitelistSubmitButton.previousElementSibling.disabled = true
|
||||||
|
if (Usernames.length > 0) {
|
||||||
|
for (let username of Usernames) {
|
||||||
|
Utilities.RatelimitRepeatingFetch('https://polytoria.com/api/create/whitelist', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
placeID: PlaceID,
|
||||||
|
username: username
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClearWhitelist() {
|
||||||
|
const WhitelistCard = document.querySelector('.card:has(#whitelist-username)')
|
||||||
|
|
||||||
|
const ClearWhitelistButton = document.createElement('button')
|
||||||
|
ClearWhitelistButton.classList = 'btn btn-danger btn-sm'
|
||||||
|
ClearWhitelistButton.style = 'position: absolute; top: 0; right: 0; margin: 4px;'
|
||||||
|
ClearWhitelistButton.innerHTML = '<i class="fa-duotone fa-solid fa-broom-wide"></i> Clear'
|
||||||
|
WhitelistCard.children[0].appendChild(ClearWhitelistButton)
|
||||||
|
|
||||||
|
let WhitelistData = null
|
||||||
|
let ClearPending = false
|
||||||
|
ClearWhitelistButton.addEventListener('click', async function(){
|
||||||
|
if (ClearPending === false) {
|
||||||
|
ClearPending = true
|
||||||
|
ClearWhitelistButton.innerText = 'Are you sure?'
|
||||||
|
setTimeout(() => {
|
||||||
|
if (ClearPending === true) {
|
||||||
|
ClearPending = false;
|
||||||
|
ClearWhitelistButton.innerHTML = '<i class="fa-duotone fa-solid fa-broom-wide"></i> Clear'
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
ClearPending = false
|
||||||
|
ClearWhitelistButton.innerHTML = '<i class="fa-duotone fa-solid fa-broom-wide"></i> Clear'
|
||||||
|
if (confirm('Are you sure you\'d like to clear all of this place\'s whitelist')) {
|
||||||
|
if (WhitelistData === null) {
|
||||||
|
const InitialWhitelist = (await (await fetch('https://polytoria.com/api/create/whitelist?placeID=' + PlaceID + '&page=1')).json())
|
||||||
|
WhitelistData = [...InitialWhitelist.data]
|
||||||
|
|
||||||
|
if (InitialWhitelist.meta.lastPage > 1) {
|
||||||
|
for (let page = 1; page < InitialWhitelist.meta.lastPage; page++) {
|
||||||
|
const PageResult = (await (await fetch('https://polytoria.com/api/create/whitelist?placeID=' + PlaceID + '&page=' + (page+1))).json())
|
||||||
|
WhitelistData.push(...PageResult.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let id of WhitelistData.map((x) => x.user.id)) {
|
||||||
|
Utilities.RatelimitRepeatingFetch('https://polytoria.com/api/create/remove-whitelist', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
placeID: PlaceID,
|
||||||
|
userID: id
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
53
js/debug.js
|
|
@ -1,53 +0,0 @@
|
||||||
// DEBUG MENU FOR CLEARING PINNED GAMES AND BEST FRIENDS
|
|
||||||
document.querySelector('#main-content .container').innerHTML = `
|
|
||||||
<button class="btn btn-warning" id="clear-pins">Clear Pinned Games</button>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<button class="btn btn-warning" id="clear-bf">Clear Best Friends</button>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<label for="settingName">Edit Setting Value</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" name="settingName" id="edit-setting-name" class="form-control" placeholder="Setting Name..">
|
|
||||||
<input type="text" id="edit-setting-value" class="form-control" placeholder="New Value..">
|
|
||||||
<button class="btn btn-warning" id="edit-setting">Submit</button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
|
|
||||||
const ClearPins = document.getElementById('clear-pins')
|
|
||||||
const ClearBF = document.getElementById('clear-bf')
|
|
||||||
const EditSettingName = document.getElementById('edit-setting-name')
|
|
||||||
const EditSettingValue = document.getElementById('edit-setting-value')
|
|
||||||
const EditSettingBtn = document.getElementById('edit-setting')
|
|
||||||
|
|
||||||
ClearPins.addEventListener('click', function(){
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': [] }, function() {
|
|
||||||
alert('Successfully cleared Pinned Games.')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ClearBF.addEventListener('click', function(){
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_BestFriends': [] }, function() {
|
|
||||||
alert('Successfully cleared Best Friends.')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
EditSettingBtn.addEventListener('click', function(){
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
|
||||||
result = result.PolyPlus_Settings
|
|
||||||
|
|
||||||
let NewValue = EditSettingValue.value
|
|
||||||
if (NewValue === "true") {NewValue = true}
|
|
||||||
if (NewValue === "false") {NewValue = false}
|
|
||||||
if (parseInt(NewValue)) {NewValue = parseInt(NewValue)}
|
|
||||||
result[EditSettingName.value] = NewValue
|
|
||||||
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_Settings': result }, function() {
|
|
||||||
alert('Successfully set: "' + EditSettingName.value + '" to ' + NewValue)
|
|
||||||
});
|
|
||||||
|
|
||||||
alert('Successfully cleared Best Friends.')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
273
js/everywhere.js
|
|
@ -1,273 +0,0 @@
|
||||||
var Settings;
|
|
||||||
const ExpectedSettings = {
|
|
||||||
PinnedGamesOn: false,
|
|
||||||
ForumMentsOn: false,
|
|
||||||
BestFriendsOn: false,
|
|
||||||
ImprovedFrListsOn: false,
|
|
||||||
IRLPriceWithCurrencyOn: true,
|
|
||||||
IRLPriceWithCurrencyCurrency: 0,
|
|
||||||
IRLPriceWithCurrencyPackage: 0,
|
|
||||||
HideNotifBadgesOn: true,
|
|
||||||
StoreOwnTagOn: true,
|
|
||||||
ThemeCreatorOn: false,
|
|
||||||
ThemeCreator: {
|
|
||||||
BGColor: null,
|
|
||||||
BGImage: null,
|
|
||||||
BGImageSize: 'fit',
|
|
||||||
PrimaryTextColor: null,
|
|
||||||
SecondaryTextColor: null,
|
|
||||||
LinkTextColor: null,
|
|
||||||
WebsiteLogo: null
|
|
||||||
},
|
|
||||||
ModifyNavOn: false,
|
|
||||||
ModifyNav: [
|
|
||||||
{
|
|
||||||
Label: "Play",
|
|
||||||
Link: "https://polytoria.com/places"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Store",
|
|
||||||
Link: "https://polytoria.com/store"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Guilds",
|
|
||||||
Link: "https://polytoria.com/guilds"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "People",
|
|
||||||
Link: "https://polytoria.com/users"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Forum",
|
|
||||||
Link: "https://polytoria.com/forum"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
MoreSearchFiltersOn: true,
|
|
||||||
ApplyMembershipThemeOn: false,
|
|
||||||
ApplyMembershipThemeTheme: 0,
|
|
||||||
ForumMarkOn: true,
|
|
||||||
MultiCancelOutTradesOn: true,
|
|
||||||
ItemWishlistOn: true,
|
|
||||||
HideUpgradeBtnOn: false
|
|
||||||
}
|
|
||||||
let Theme = null;
|
|
||||||
|
|
||||||
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
|
|
||||||
// Merge settings and expected settings to make sure all keys exist
|
|
||||||
let RawSettings = result.PolyPlus_Settings
|
|
||||||
Settings = MergeObjects(RawSettings || ExpectedSettings, ExpectedSettings);
|
|
||||||
//chrome.storage.sync.set({ 'PolyPlus_Settings': Settings, arrayOrder: true }, function() {});
|
|
||||||
|
|
||||||
// If theme exists, create a style element to represent it
|
|
||||||
if (Settings.ThemeCreatorOn && Settings.ThemeCreatorOn === true) {
|
|
||||||
Theme = document.createElement('style')
|
|
||||||
switch (Settings.ThemeCreator.BGImageSize) {
|
|
||||||
case 0:
|
|
||||||
Settings.ThemeCreator.BGImageSize = 'fit'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
Settings.ThemeCreator.BGImageSize = 'cover'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
Settings.ThemeCreator.BGImageSize = 'contain'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Theme.innerHTML = `
|
|
||||||
:root {
|
|
||||||
--polyplus-navbgcolor: ${Settings.ThemeCreator.NavBGColor};
|
|
||||||
--polyplus-navbordercolor: ${Settings.ThemeCreator.NavBorderColor};
|
|
||||||
--polyplus-navitemcolor: ${Settings.ThemeCreator.NavItemColor};
|
|
||||||
--polyplus-sidebarbgcolor: ${Settings.ThemeCreator.SideBGColor};
|
|
||||||
--polyplus-sidebarbordercolor: ${Settings.ThemeCreator.SideBorderColor};
|
|
||||||
--polyplus-sidebaritembgcolor: ${Settings.ThemeCreator.SideItemBGColor};
|
|
||||||
--polyplus-sidebaritembordercolor: ${Settings.ThemeCreator.SideItemBorderColor};
|
|
||||||
--polyplus-sidebaritemcolor: ${Settings.ThemeCreator.SideItemColor};
|
|
||||||
--polyplus-sidebaritemlabelcolor: ${Settings.ThemeCreator.SideItemLabelColor};
|
|
||||||
--polyplus-bgcolor: ${Settings.ThemeCreator.BGColor};
|
|
||||||
--polyplus-bgimage: url(${Settings.ThemeCreator.BGImage});
|
|
||||||
--polyplus-bgimagesize: ${Settings.ThemeCreator.BGImageSize};
|
|
||||||
--polyplus-primarytextcolor: ${Settings.ThemeCreator.PrimaryTextColor};
|
|
||||||
--polyplus-secondarytextcolor: ${Settings.ThemeCreator.SecondaryTextColor};
|
|
||||||
--polyplus-linktextcolor: ${Settings.ThemeCreator.LinkTextColor};
|
|
||||||
--polyplus-linkhoveredtextcolor: ${Settings.ThemeCreator.LinkHoveredTextColor};
|
|
||||||
--polyplus-linkfocusedtextcolor: ${Settings.ThemeCreator.LinkFocusedTextColor};
|
|
||||||
--polyplus-linkvisitedtextcolor: ${Settings.ThemeCreator.LinkVisitedTextColor};
|
|
||||||
--polyplus-cardheadbgcolor: ${Settings.ThemeCreator.CardHeadBGColor};
|
|
||||||
--polyplus-cardbodybgcolor: ${Settings.ThemeCreator.CardBodyBGColor};
|
|
||||||
--polyplus-cardbordercolor: ${Settings.ThemeCreator.CardBorderColor};
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
background-color: var(--polyplus-navbgcolor) !important;
|
|
||||||
border-bottom: 1px solid var(--polyplus-navbordercolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar {
|
|
||||||
background-color: var(--polyplus-sidebarbgcolor) !important;
|
|
||||||
border-right: 1px solid var(--polyplus-sidebarbordercolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
background-color: var(--polyplus-bgcolor) !important;
|
|
||||||
background-image: var(--polyplus-bgimage) !important;
|
|
||||||
background-size var(--polyplus-bgimagesize)
|
|
||||||
color: var(--polyplus-primarytextcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-muted {
|
|
||||||
color: var(--polyplus-secondarytextcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--polyplus-linktextcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--polyplus-linkhoveredtextcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:focus {
|
|
||||||
color: var(--polyplus-linkfocusedtextcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
a:visited {
|
|
||||||
color: var(--polyplus-linkvisitedtextcolor) !important;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
background-color: var(--polyplus-cardheadbgcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
background-color: var(--polyplus-cardbodybgcolor) !important;
|
|
||||||
border-color: var(--polyplus-cardbordercolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a.nav-link {
|
|
||||||
color: var(--polyplus-navitemcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar .nav-sidebar-button {
|
|
||||||
background-color: var(--polyplus-sidebaritembgcolor) !important;
|
|
||||||
border-color: var(--polyplus-sidebaritembordercolor) !important;
|
|
||||||
color: var(--polyplus-sidebaritemcolor) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-sidebar-text {
|
|
||||||
color: var(--polyplus-sidebaritemlabelcolor) !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', 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 = {
|
|
||||||
Username: document.querySelector('a.text-reset.text-decoration-none[href^="/users"]').innerText.replace(/\s+/g,''),
|
|
||||||
ID: document.querySelector('.text-reset.text-decoration-none[href^="/users/"]').getAttribute('href').split('/')[2],
|
|
||||||
Bricks: document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g,'')
|
|
||||||
}
|
|
||||||
|
|
||||||
window.localStorage.setItem('account_info', JSON.stringify(UserData))
|
|
||||||
document.body.setAttribute('data-URL', window.location.href)
|
|
||||||
|
|
||||||
// Add PolyPlus Settings link to Sidebar
|
|
||||||
const Parent = document.querySelector('ul.nav.nav-flush')
|
|
||||||
const Clone = Parent.querySelectorAll('li.nav-item')[0].cloneNode(true)
|
|
||||||
Clone.getElementsByTagName('a')[0].href = '/my/settings/polyplus'
|
|
||||||
Clone.getElementsByTagName('span')[0].innerText = "Poly+"
|
|
||||||
const Icon = Clone.querySelector('i')
|
|
||||||
Icon.classList = 'fa-regular fa-sparkles'
|
|
||||||
|
|
||||||
if (Settings.ModifyNavOn && Settings.ModifyNavOn === true) {
|
|
||||||
let NavbarItems = document.querySelectorAll('#main-content nav.navbar .nav-link')
|
|
||||||
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) {
|
|
||||||
Needed[i].children[1].innerText = Settings.ModifyNav[i].Label
|
|
||||||
Needed[i].href = Settings.ModifyNav[i].Link
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.HideUpgradeBtnOn && Settings.HideUpgradeBtnOn === true) {
|
|
||||||
document.querySelector('.nav-sidebar a[href="/upgrade"].nav-link.py-1.nav-sidebar-link').remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.IRLPriceWithCurrencyOn && Settings.IRLPriceWithCurrencyOn === true) {
|
|
||||||
var IRL;
|
|
||||||
var DISPLAY;
|
|
||||||
switch (Settings.IRLPriceWithCurrencyCurrency) {
|
|
||||||
case 0:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.0099).toFixed(2)
|
|
||||||
DISPLAY = 'USD'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.009).toFixed(2)
|
|
||||||
DISPLAY = 'EUR'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.0131).toFixed(2)
|
|
||||||
DISPLAY = 'CAD'
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.0077).toFixed(2)
|
|
||||||
DISPLAY = 'GBP'
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.1691).toFixed(2)
|
|
||||||
DISPLAY = 'MXN'
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.0144).toFixed(2)
|
|
||||||
DISPLAY = 'AUD'
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
IRL = (UserData.Bricks.replace(/,/g, '') * 0.2338).toFixed(2)
|
|
||||||
DISPLAY = 'TRY'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
let BrickBalanceCount = [document.querySelector('.text-success .brickBalanceCount'), document.querySelector('.text-success .brickBalanceCont')]
|
|
||||||
BrickBalanceCount.forEach(element => {
|
|
||||||
element.innerText = element.innerText + ` ($${IRL} ${DISPLAY})`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.HideNotifBadgesOn && Settings.HideNotifBadgesOn === true) {
|
|
||||||
document.querySelectorAll('.notif-nav.notif-sidebar').forEach(element => {element.remove();});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
512
js/extra-pages.js
Normal file
|
|
@ -0,0 +1,512 @@
|
||||||
|
/*
|
||||||
|
Developer & Debug Page
|
||||||
|
Accessable at /my/settings/polyplus#dev and /my/settings/polyplus#debug
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.title = 'Poly+ Debug - Polytoria';
|
||||||
|
const Version = chrome.runtime.getManifest().version;
|
||||||
|
|
||||||
|
if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.hash === '#dev') {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
document.querySelector('#main-content .container').innerHTML = `
|
||||||
|
<style>
|
||||||
|
#main-content .container label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-content .container label + p {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="text-center mb-3">
|
||||||
|
<h1 class="text-center" style="font-size: 4.6rem;">Poly+ Developer</h1>
|
||||||
|
<p class="w-75 d-block mx-auto">This page is used by developers for debugging most data related things. It is unrecommended you modify any data on this page, but if you ever want to go ahead.</p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2" style="padding-left: 0px;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="text-muted mb-1">Version: v${Version}</p>
|
||||||
|
<p class="text-muted mb-3">Data Size: <span id="data-size">Loading</span> byte(s)</p>
|
||||||
|
<button class="btn btn-primary btn-sm w-100" id="check-for-updates">Check for Updates</button>
|
||||||
|
<a href="https://github.com/indexxing/PolyPlus" class="btn btn-dark btn-sm w-100 mt-2" target="_blank">Open GitHub</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
Created by <a href="/u/Index" target="_blank">Index</a>
|
||||||
|
<br><br>
|
||||||
|
Beta Testers:
|
||||||
|
<ul>
|
||||||
|
<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">
|
||||||
|
<label for="settingName">Edit Setting Value</label>
|
||||||
|
<p>Set a value of the extension's local settings data</p>
|
||||||
|
<div role="group" class="input-group mb-3">
|
||||||
|
<input type="text" name="settingName" id="edit-setting-name" class="form-control" placeholder="Setting Name..">
|
||||||
|
<input type="text" id="edit-setting-value" class="form-control" placeholder="New Value..">
|
||||||
|
<button class="btn btn-success w-25" id="edit-setting">Submit</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Load Example Data</label>
|
||||||
|
<p>Quickly clear specific parts of the extension's local data</p>
|
||||||
|
<div role="group" class="btn-group w-100 mb-3">
|
||||||
|
<button class="btn btn-secondary" id="example-pinnedgames">Load Example Pinned Games</button>
|
||||||
|
<button class="btn btn-secondary" id="example-bestfriends">Load Example Best Friends</button>
|
||||||
|
<button class="btn btn-secondary" id="example-itemwishlist">Load Example Item Wishlist</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Clear Specific Local Data</label>
|
||||||
|
<p>Quickly clear specific parts of the extension's local data</p>
|
||||||
|
<div role="group" class="btn-group w-100 mb-3">
|
||||||
|
<button class="btn btn-secondary" id="reset-settings">Reset Settings to Defaults</button>
|
||||||
|
<button class="btn btn-secondary" id="clear-pinnedgames">Clear Pinned Games</button>
|
||||||
|
<button class="btn btn-secondary" id="clear-bestfriends">Clear Best Friends</button>
|
||||||
|
<button class="btn btn-secondary" id="clear-itemwishlist">Clear Item Wishlist</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header text-primary">Tools</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<label>Generate <code style="color: orange;">JSON</code> for "Event Items" store category</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control bg-dark" placeholder="Event ID..">
|
||||||
|
<input type="text" class="form-control bg-dark" placeholder="Item IDs (separated by commas)..">
|
||||||
|
<button class="btn btn-primary" id="generate-event-items">Generate</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header" style="color: red;">Danger Zone!</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<label>Clear Specific Data Locations</label>
|
||||||
|
<p>Quickly clear specific locations of the extension's local data</p>
|
||||||
|
<div role="group" class="btn-group w-100 mb-3">
|
||||||
|
<button class="btn btn-primary" id="delete-sync">Delete Sync Storage (primary, storage is backed up to Google account)</button>
|
||||||
|
<button class="btn btn-secondary" id="delete-local">Delete Local Storage (secondary, storage is only on local device)</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Delete All Data</label>
|
||||||
|
<p>This will clear all local data associated with the extension</p>
|
||||||
|
<button class="btn btn-danger w-100 mb-3" id="delete-all-data">Delete All Data</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 === Version || Math.floor((data.version - Version) * 10) === 0) {
|
||||||
|
CheckForUpdatesButton.innerText = 'No updates available';
|
||||||
|
} else {
|
||||||
|
CheckForUpdatesButton.innerText = Math.floor((data.version - Version) * 10) + ' updates available';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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');
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
|
result = result.PolyPlus_Settings;
|
||||||
|
|
||||||
|
let NewValue = EditSettingValue.value;
|
||||||
|
switch (NewValue) {
|
||||||
|
case 'true':
|
||||||
|
NewValue = true;
|
||||||
|
break;
|
||||||
|
case 'false':
|
||||||
|
NewValue = false;
|
||||||
|
break;
|
||||||
|
case 'null':
|
||||||
|
NewValue = null;
|
||||||
|
break;
|
||||||
|
case 'undefined':
|
||||||
|
NewValue = undefined;
|
||||||
|
break;
|
||||||
|
case parseInt(NewValue):
|
||||||
|
NewValue = parseInt(NewValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result[EditSettingName.value] = 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!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('example-pinnedgames').addEventListener('click', function () {
|
||||||
|
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!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('example-itemwishlist').addEventListener('click', function () {
|
||||||
|
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!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('clear-bestfriends').addEventListener('click', function () {
|
||||||
|
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!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
chrome.storage.sync.clear(function () {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
chrome.storage.local.clear(function () {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
chrome.storage.sync.clear(function () {
|
||||||
|
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!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const GenerateEventItems = document.getElementById('generate-event-items')
|
||||||
|
GenerateEventItems.addEventListener('click', async function(){
|
||||||
|
const EventItemsJSON = []
|
||||||
|
const ItemIDs = GenerateEventItems.previousElementSibling.value.split(',')
|
||||||
|
for (let id of ItemIDs) {
|
||||||
|
const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + id.trim())).json())
|
||||||
|
EventItemsJSON.push({
|
||||||
|
id: parseInt(id),
|
||||||
|
name: ItemDetails.name,
|
||||||
|
event: GenerateEventItems.previousElementSibling.previousElementSibling.value,
|
||||||
|
thumbnail: ItemDetails.thumbnail
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(EventItemsJSON)
|
||||||
|
|
||||||
|
navigator.clipboard.writeText(JSON.stringify(EventItemsJSON, null, 2))
|
||||||
|
.then(() => {
|
||||||
|
alert('Successfully copied generated event items JSON!')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure when trying to copy generated event items JSON.')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
chrome.storage.sync.getBytesInUse(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_ItemWishlist', 'PolyPlus_TimePlayed', 'PolyPlus_AvatarSandboxOutfits'], function (sync) {
|
||||||
|
chrome.storage.local.getBytesInUse(['PolyPlus_InventoryCache', 'PolyPlus_GreatDivideStats'], function(local){
|
||||||
|
document.getElementById('data-size').innerText = (sync + local).toLocaleString();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.hash === '#debug') {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_BestFriends', 'PolyPlus_ItemWishlist', 'PolyPlus_AvatarSandboxOutfits', 'PolyPlus_TimePlayed'], function(sync) {
|
||||||
|
chrome.storage.local.get(['PolyPlus_InventoryCache', 'PolyPlus_GreatDivideStats', 'PolyPlus_FriendCount', 'PolyPlus_AssetDesigners'], function(local){
|
||||||
|
document.querySelector('#main-content .container').innerHTML = `
|
||||||
|
<style>
|
||||||
|
#main-content .container label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-content .container label + p {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:has([data-bs-toggle="collapse"]):not(:has(.card-body.collapse.show)) a:has(.card-header), .card:has([data-bs-toggle="collapse"]):not(:has(.card-body.collapse.show)) .card-header, .card:has([data-bs-toggle="collapse"]):has(.card-body.collapse.collapsing) a:has(.card-header), .card:has([data-bs-toggle="collapse"]):has(.card-body.collapse.collapsing) .card-header {
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="text-center mb-3">
|
||||||
|
<h1 class="text-center" style="font-size: 4.6rem;">Poly+ Debug</h1>
|
||||||
|
<p class="w-75 d-block mx-auto mb-0">This page is used for accessing most data-related objects stored by the extension.</p>
|
||||||
|
<small style="font-size: 0.75rem;" class="text-muted">* note: cache objects don't get cleared, instead when they are requested, if the data stored is old, new data will replace the old data.</small>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2" style="padding-left: 0px;">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="text-muted mb-1">Version: v${Version}</p>
|
||||||
|
<p class="text-muted mb-3">Data Size: <span id="data-size">Loading</span> byte(s)</p>
|
||||||
|
<button class="btn btn-primary btn-sm w-100" id="check-for-updates">Check for Updates</button>
|
||||||
|
<a href="https://github.com/indexxing/PolyPlus" class="btn btn-dark btn-sm w-100 mt-2" target="_blank">Open GitHub</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
Created by <a href="/u/Index" target="_blank">Index</a>
|
||||||
|
<br><br>
|
||||||
|
Beta Testers:
|
||||||
|
<ul>
|
||||||
|
<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">
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#settings" role="button" aria-expanded="false" aria-controls="settings">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-primary" style="margin-right: 5px; vertical-align: text-bottom;">Sync</span>
|
||||||
|
Settings
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="settings">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((sync.PolyPlus_Settings || {}), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#pinned-games" role="button" aria-expanded="false" aria-controls="pinned-games">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-primary" style="margin-right: 5px; vertical-align: text-bottom;">Sync</span>
|
||||||
|
Pinned Games
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(${(sync.PolyPlus_PinnedGames || []).length})</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="pinned-games">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((sync.PolyPlus_PinnedGames || []), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
<button class="btn btn-warning btn-sm" style="position: absolute; top: 0; right: 0; margin: 10px;" onclick="navigator.clipboard.writeText('${JSON.stringify((sync.PolyPlus_PinnedGames || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#item-wishlist" role="button" aria-expanded="false" aria-controls="item-wishlist">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-primary" style="margin-right: 5px; vertical-align: text-bottom;">Sync</span>
|
||||||
|
Item Wishlist
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(${(sync.PolyPlus_ItemWishlist || []).length})</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="item-wishlist">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((sync.PolyPlus_ItemWishlist || []), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
<button class="btn btn-warning btn-sm" style="position: absolute; top: 0; right: 0; margin: 10px;" onclick="navigator.clipboard.writeText('${JSON.stringify((sync.PolyPlus_ItemWishlist || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#avatar-sandbox-outfits" role="button" aria-expanded="false" aria-controls="item-wishlist">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-primary" style="margin-right: 5px; vertical-align: text-bottom;">Sync</span>
|
||||||
|
Avatar Sandbox Outfits
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(${(sync.PolyPlus_AvatarSandboxOutfits || []).length})</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="avatar-sandbox-outfits">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((sync.PolyPlus_AvatarSandboxOutfits || []), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
<button class="btn btn-warning btn-sm" style="position: absolute; top: 0; right: 0; margin: 10px;" onclick="navigator.clipboard.writeText('${JSON.stringify((sync.PolyPlus_AvatarSandboxOutfits || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#time-played" role="button" aria-expanded="false" aria-controls="item-wishlist">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-primary" style="margin-right: 5px; vertical-align: text-bottom;">Sync</span>
|
||||||
|
Time Played
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(${(Object.keys(sync.PolyPlus_TimePlayed) || []).length} places tracked)</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="time-played">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((sync.PolyPlus_TimePlayed || []), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
<button class="btn btn-warning btn-sm" style="position: absolute; top: 0; right: 0; margin: 10px;" onclick="navigator.clipboard.writeText('${JSON.stringify((sync.PolyPlus_AvatarSandboxOutfits || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#inventory-cache" role="button" aria-expanded="false" aria-controls="inventory-cache">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-secondary" style="margin-right: 5px; vertical-align: text-bottom;">Local</span>
|
||||||
|
Inventory Cache
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(cached for 5 minutes, ${local.PolyPlus_InventoryCache.data.length} items cached)</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="inventory-cache">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((local.PolyPlus_InventoryCache || {data: [], requested: "never"}), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#great-divide-stats" role="button" aria-expanded="false" aria-controls="inventory-cache">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-secondary" style="margin-right: 5px; vertical-align: text-bottom;">Local</span>
|
||||||
|
Great Divide User Statistics
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(cached for 5 minutes, ${Object.keys(local.PolyPlus_GreatDivideStats || {}).length} users cached)</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="great-divide-stats">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((local.PolyPlus_GreatDivideStats || {}), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#friend-count" role="button" aria-expanded="false" aria-controls="inventory-cache">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-secondary" style="margin-right: 5px; vertical-align: text-bottom;">Local</span>
|
||||||
|
Friend Count
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(cached for 5 minutes)</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="friend-count">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((local.PolyPlus_FriendCount || {data: [], requested: "never"}), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mb-3">
|
||||||
|
<a class="text-reset" data-bs-toggle="collapse" href="#asset-designers" role="button" aria-expanded="false" aria-controls="inventory-cache">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="badge bg-secondary" style="margin-right: 5px; vertical-align: text-bottom;">Local</span>
|
||||||
|
Asset Designers Cache
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">(cached for 5 minutes)</small>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="card-body collapse" id="asset-designers">
|
||||||
|
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||||
|
${JSON.stringify((local.PolyPlus_AssetDesigners || {data: {}, requested: "never"}), null, 2)
|
||||||
|
.replaceAll('\n','<br>')
|
||||||
|
.replaceAll(' ', ' ')
|
||||||
|
.replaceAll('\t', ' ')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 === Version || Math.floor((data.version - Version) * 10) === 0) {
|
||||||
|
CheckForUpdatesButton.innerText = 'No updates available';
|
||||||
|
} else {
|
||||||
|
CheckForUpdatesButton.innerText = Math.floor((data.version - Version) * 10) + ' updates available';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
CheckForUpdatesButton.addEventListener('click', CheckForUpdates);
|
||||||
|
|
||||||
|
chrome.storage.sync.getBytesInUse(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_ItemWishlist', 'PolyPlus_TimePlayed', 'PolyPlus_AvatarSandboxOutfits'], function (sync) {
|
||||||
|
chrome.storage.local.getBytesInUse(['PolyPlus_InventoryCache'], function(local){
|
||||||
|
document.getElementById('data-size').innerText = (sync + local).toLocaleString();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,40 +1,40 @@
|
||||||
setTimeout(function () {}, 100)
|
setTimeout(function () {}, 100);
|
||||||
var Settings;
|
var Settings;
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
Settings = result.PolyPlus_Settings;
|
Settings = result.PolyPlus_Settings;
|
||||||
|
|
||||||
if (!(Settings.MoreSearchFiltersOn === true)) {
|
if (!(Settings.MoreSearchFiltersOn === true)) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Form = document.querySelector('form[action="/forum/search"]')
|
let Form = document.querySelector('form[action="/forum/search"]');
|
||||||
let SearchBtn = document.querySelector('button[type="submit"]')
|
let SearchBtn = document.querySelector('button[type="submit"]');
|
||||||
let CreatedByFilter = document.createElement('div')
|
let CreatedByFilter = document.createElement('div');
|
||||||
CreatedByFilter.classList = 'input-group mt-2'
|
CreatedByFilter.classList = 'input-group mt-2';
|
||||||
CreatedByFilter.innerHTML = `
|
CreatedByFilter.innerHTML = `
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input class="form-check-input" type="checkbox">
|
<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>
|
<label class="form-check-label" for="createdBy">Created by <input type="text" class="form-control" placeholder="willemsteller" id="createdBy" name="createdBy"></label>
|
||||||
</div>
|
</div>
|
||||||
`
|
`;
|
||||||
console.log(SearchBtn)
|
console.log(SearchBtn);
|
||||||
Form.insertBefore(CreatedByFilter, SearchBtn.parentElement)
|
Form.insertBefore(CreatedByFilter, SearchBtn.parentElement);
|
||||||
let CreatedByFilter_Checkbox = CreatedByFilter.querySelector('input[type="checkbox"]')
|
let CreatedByFilter_Checkbox = CreatedByFilter.querySelector('input[type="checkbox"]');
|
||||||
let CreatedByFilter_Input = CreatedByFilter.querySelector('input[type="text"]')
|
let CreatedByFilter_Input = CreatedByFilter.querySelector('input[type="text"]');
|
||||||
let CreatedByValue = GetURLParameter("createdBy")
|
let CreatedByValue = GetURLParameter('createdBy');
|
||||||
console.log(CreatedByValue)
|
console.log(CreatedByValue);
|
||||||
if (CreatedByValue) {
|
if (CreatedByValue) {
|
||||||
CreatedByFilter_Checkbox.setAttribute('checked', true)
|
CreatedByFilter_Checkbox.setAttribute('checked', true);
|
||||||
CreatedByFilter_Input.setAttribute('value', CreatedByValue)
|
CreatedByFilter_Input.setAttribute('value', CreatedByValue);
|
||||||
CreatedByFilter_Input.removeAttribute('disabled')
|
CreatedByFilter_Input.removeAttribute('disabled');
|
||||||
document.querySelectorAll('.forum-entry').forEach(element => {
|
document.querySelectorAll('.forum-entry').forEach((element) => {
|
||||||
console.log(element.querySelectorAll('a[href^="/users/"]')[1].innerText)
|
console.log(element.querySelectorAll('a[href^="/users/"]')[1].innerText);
|
||||||
if (!(element.querySelectorAll('a[href^="/users/"]')[1].innerText === CreatedByValue)) {
|
if (!(element.querySelectorAll('a[href^="/users/"]')[1].innerText === CreatedByValue)) {
|
||||||
element.remove();
|
element.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
CreatedByFilter_Checkbox.addEventListener('click', function(){
|
CreatedByFilter_Checkbox.addEventListener('click', function(){
|
||||||
let Status = CreatedByFilter_Checkbox.getAttribute('checked')
|
let Status = CreatedByFilter_Checkbox.getAttribute('checked')
|
||||||
if (Status === true) {
|
if (Status === true) {
|
||||||
|
|
@ -47,7 +47,7 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
||||||
});
|
});
|
||||||
|
|
||||||
function GetURLParameter(param) {
|
function GetURLParameter(param) {
|
||||||
const queryString = window.location.search;
|
const queryString = window.location.search;
|
||||||
const urlParams = new URLSearchParams(queryString);
|
const urlParams = new URLSearchParams(queryString);
|
||||||
return urlParams.get(param);
|
return urlParams.get(param);
|
||||||
}
|
}
|
||||||
|
|
@ -1,51 +1,58 @@
|
||||||
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) {
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
Settings = result.PolyPlus_Settings || {
|
Settings = result.PolyPlus_Settings || {
|
||||||
ForumMentsOn: false,
|
ForumMentsOn: false,
|
||||||
ForumUnixStampsOn: false
|
ForumUnixStampsOn: false
|
||||||
}
|
};
|
||||||
|
|
||||||
if (Settings.ForumMentsOn === true) {
|
if (Settings.ForumMentsOn === true) {
|
||||||
HandleForumMentions()
|
ForumMentions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.ForumUnixStampsOn === true) {
|
if (Settings.ForumUnixStampsOn === true) {
|
||||||
HandleUnixTimestamps()
|
ForumUnixTimestamps();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function HandleForumMentions() {
|
function ForumMentions() {
|
||||||
const Regex = /@([\w.]+)/g
|
const Regex = /@([\w.]+)/g;
|
||||||
|
|
||||||
for (let text of ForumText) {
|
for (let text of ForumText) {
|
||||||
let FormattedText = text.innerHTML
|
const TreeWalker = document.createTreeWalker(text, NodeFilter.SHOW_TEXT, null, false);
|
||||||
let match;
|
let Node;
|
||||||
while ((match = Regex.exec(text.innerText)) !== null) {
|
|
||||||
const Username = match[0].substring(1)
|
while ((Node = TreeWalker.nextNode())) {
|
||||||
FormattedText = FormattedText.replaceAll(match[0], `<a href="/profile/${Username}?ref=${encodeURIComponent(window.location.pathname)}" class="polyplus-mention">${match[0]}</a>`)
|
let Match;
|
||||||
|
let Replacement = Node.nodeValue;
|
||||||
|
|
||||||
|
while ((Match = Regex.exec(Node.nodeValue)) !== null) {
|
||||||
|
const Username = Match[0].substring(1);
|
||||||
|
const Mention = `<a href="/u/${Username}" class="polyplus-mention">${Match[0]}</a>`;
|
||||||
|
Replacement = replacedText.replace(Match[0], Mention);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node.nodeValue = replacedText;
|
||||||
}
|
}
|
||||||
text.innerHTML = FormattedText
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function HandleUnixTimestamps() {
|
function ForumUnixTimestamps() {
|
||||||
const Regex = /<t:[A-Za-z0-9]+>/i
|
const Regex = /<t:[A-Za-z0-9]+>/i;
|
||||||
|
|
||||||
for (let text of ForumText) {
|
for (let text of ForumText) {
|
||||||
let FormattedText = text.innerHTML
|
let FormattedText = text.innerHTML;
|
||||||
let match;
|
let match;
|
||||||
|
|
||||||
while ((match = Regex.exec(FormattedText)) !== null) {
|
while ((match = Regex.exec(FormattedText)) !== null) {
|
||||||
const Timestamp = new Date(match[0].substring(6, match[0].length - 4) * 1000)
|
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 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 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>`
|
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)
|
FormattedText = FormattedText.replaceAll(match[0], Result);
|
||||||
console.log(FormattedText)
|
}
|
||||||
}
|
text.innerHTML = FormattedText;
|
||||||
text.innerHTML = FormattedText
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
52
js/guilds.js
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
const StoreItems = document.getElementById('store-items');
|
||||||
|
|
||||||
|
var Settings;
|
||||||
|
let Utilities;
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
|
Settings = result.PolyPlus_Settings;
|
||||||
|
|
||||||
|
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
|
(async () => {
|
||||||
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default;
|
||||||
|
|
||||||
|
for (let item of Array.from(StoreItems.children)) {
|
||||||
|
IRLPrice(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PreviousPage = document.querySelector('#store-prev a');
|
||||||
|
const NextPage = document.querySelector('#store-next a');
|
||||||
|
//PreviousPage.addEventListener('click', IRLPrice)
|
||||||
|
//NextPage.addEventListener('click', IRLPrice)
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
|
IRLPrice(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
observer.observe(StoreItems, {attributes: false, childList: true, subtree: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(StoreItems, {attributes: false, childList: true, subtree: false});
|
||||||
137
js/library-download.js
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
const AssetID = window.location.pathname.split('/')[2];
|
||||||
|
const LibraryType = document.querySelectorAll('ol a')[1].innerText.toLowerCase();
|
||||||
|
const LibraryTypes = ['model', 'audio', 'decal', 'mesh', 'shirt', 'pant'];
|
||||||
|
|
||||||
|
if (LibraryTypes.some(element => LibraryType.startsWith(element))) {
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
||||||
|
Settings = result.PolyPlus_Settings || {};
|
||||||
|
|
||||||
|
if (['model', 'audio', 'decal', 'mesh'].some(element => LibraryType.startsWith(element))) {
|
||||||
|
const Breadcrumbs = document.querySelectorAll('ol a')
|
||||||
|
Breadcrumbs[0].href = '/library'
|
||||||
|
Breadcrumbs[0].innerText = 'Library'
|
||||||
|
Breadcrumbs[1].href = '/library'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.LibraryDownloadsOn === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 SourceLink = document.createElement('a');
|
||||||
|
SourceLink.classList = 'dropdown-item text-primary';
|
||||||
|
SourceLink.href = '#';
|
||||||
|
SourceLink.innerHTML = `<i class="fa-duotone fa-copy"></i> Copy CDN URL`;
|
||||||
|
|
||||||
|
if (LibraryType.startsWith('audio') || LibraryType.startsWith('decal') || LibraryType.startsWith('shirt') || LibraryType.startsWith('pant') || LibraryType.startsWith('mesh')) {
|
||||||
|
Dropdown.insertBefore(SourceLink, DownloadLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (LibraryType) {
|
||||||
|
case LibraryType.startsWith('model'):
|
||||||
|
DownloadLink.href = 'https://api.polytoria.com/v1/models/get-model?id=' + AssetID;
|
||||||
|
break;
|
||||||
|
case LibraryType.startsWith('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';
|
||||||
|
|
||||||
|
console.log('aaaaa')
|
||||||
|
SourceLink.addEventListener('click', function() {
|
||||||
|
console.log('LCICKED!!')
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(document.getElementsByTagName('audio')[0].src)
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure to copy .png file CDN url to clipboard')
|
||||||
|
});
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case (LibraryType.startsWith('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;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LibraryType.startsWith('shirt') || LibraryType.startsWith('pant') || LibraryType.startsWith('decal')) {
|
||||||
|
let ClothingURL = null;
|
||||||
|
DownloadLink.addEventListener('click', async function () {
|
||||||
|
if (ClothingURL !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClothingURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + AssetID + '/Asset')).json());
|
||||||
|
|
||||||
|
if (ClothingURL.success === true) {
|
||||||
|
const ClothingBlob = (await (await fetch(ClothingURL.url)).blob())
|
||||||
|
DownloadLink.href = URL.createObjectURL(ClothingBlob);
|
||||||
|
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.png';
|
||||||
|
|
||||||
|
DownloadLink.click();
|
||||||
|
} else {
|
||||||
|
alert('Failure to fetch .png file for clothing item');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SourceLink.addEventListener('click', async function(){
|
||||||
|
if (ClothingURL !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClothingURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + AssetID + '/Asset')).json());
|
||||||
|
|
||||||
|
if (ClothingURL.success === true) {
|
||||||
|
navigator.clipboard.writeText(ClothingURL.url)
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure to copy .png file CDN url to clipboard')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alert('Failure to fetch .png file for clothing item');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (LibraryType.startsWith('mesh')) {
|
||||||
|
let MeshURL = null;
|
||||||
|
DownloadLink.addEventListener('click', async function () {
|
||||||
|
if (MeshURL !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + AssetID)).json());
|
||||||
|
|
||||||
|
if (MeshURL.success === true) {
|
||||||
|
DownloadLink.href = MeshURL.url;
|
||||||
|
DownloadLink.download = document.getElementsByTagName('h1')[0].innerText + '.glb';
|
||||||
|
|
||||||
|
DownloadLink.click();
|
||||||
|
} else {
|
||||||
|
alert('Failure to fetch .glb file for mesh');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SourceLink.addEventListener('click', async function(){
|
||||||
|
if (MeshURL !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + AssetID)).json());
|
||||||
|
|
||||||
|
if (MeshURL.success === true) {
|
||||||
|
navigator.clipboard.writeText(MeshURL.url)
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Failure to copy .glb file CDN url to clipboard')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alert('Failure to fetch .glb file for mesh');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,46 +1,55 @@
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
Settings = result.PolyPlus_Settings || {
|
Settings = result.PolyPlus_Settings || {
|
||||||
ApplyMembershipThemeOn: false,
|
ApplyMembershipTheme: {
|
||||||
ApplyMembershipThemeTheme: 0
|
Enabled: false,
|
||||||
};
|
Theme: 0
|
||||||
if (Settings.ApplyMembershipThemeOn !== true) {return}
|
},
|
||||||
|
ApplyMembershipThemeOn: false,
|
||||||
|
ApplyMembershipThemeTheme: 0
|
||||||
|
};
|
||||||
|
if (Settings.ApplyMembershipTheme.Enabled !== true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MembershipTheme = Settings.ApplyMembershipThemeTheme === 0 ? 'plus': 'plusdx'
|
MembershipTheme = Settings.ApplyMembershipTheme.Theme === 0 ? 'plus' : 'plusdx';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function(){
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
|
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) {
|
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');
|
const Navbar = document.querySelector('.navbar.navbar-expand-lg.navbar-light.bg-navbar.nav-topbar');
|
||||||
const Sidebar = document.querySelector('.d-flex.flex-column.flex-shrink-0.bg-sidebar.nav-sidebar');
|
const Sidebar = document.querySelector('.d-flex.flex-column.flex-shrink-0.bg-sidebar.nav-sidebar');
|
||||||
|
|
||||||
Navbar.classList.add('navbar-' + MembershipTheme);
|
Navbar.classList.add('navbar-' + MembershipTheme);
|
||||||
Sidebar.classList.add('sidebar-' + MembershipTheme);
|
Sidebar.classList.add('sidebar-' + MembershipTheme);
|
||||||
|
|
||||||
if (MembershipTheme === 'plusdx') {
|
let SidebarLogo = Sidebar.getElementsByTagName('img')[0];
|
||||||
let SidebarLogo = document.querySelector('.nav-sidebar img');
|
if (MembershipTheme === 'plus') {
|
||||||
SidebarLogo.setAttribute('src', 'https://c0.ptacdn.com/static/images/branding/icon-plusdx.bd9daa92.svg')
|
SidebarLogo.src = 'https://c0.ptacdn.com/static/images/branding/icon-plus.8f6e41f1.svg'
|
||||||
let SidebarLogoLabel = document.createElement('div')
|
} else {
|
||||||
SidebarLogoLabel.classList = 'nplusdx-banner'
|
SidebarLogo.src = 'https://c0.ptacdn.com/static/images/branding/icon-plusdx.bd9daa92.svg'
|
||||||
SidebarLogoLabel.innerHTML = `
|
}
|
||||||
<i class="pi pi-plusdx" style="margin-right:-0.4em"></i>
|
|
||||||
`
|
|
||||||
SidebarLogo.parentElement.appendChild(SidebarLogoLabel)
|
|
||||||
|
|
||||||
if (window.location.pathname === "/home") {
|
let SidebarLogoLabel = document.createElement('div');
|
||||||
let HomeUsernameText = document.getElementsByClassName('home-title2')[0]
|
SidebarLogoLabel.classList = 'n' + MembershipTheme + '-banner';
|
||||||
HomeUsernameText.children[0].classList.add('text-plusdx')
|
SidebarLogoLabel.innerHTML = `
|
||||||
let Label = document.createElement('div')
|
<i class="pi pi-${MembershipTheme}" style="margin-right:-0.4em"></i>
|
||||||
Label.classList = 'hplusdx-banner rounded-2'
|
`;
|
||||||
Label.setAttribute('style', 'margin-top: -8px; animation-delay: 0.09s;')
|
SidebarLogo.parentElement.appendChild(SidebarLogoLabel);
|
||||||
Label.innerText = 'Deluxe'
|
|
||||||
HomeUsernameText.appendChild(Label)
|
if (MembershipTheme === 'plusdx' && window.location.pathname === '/home') {
|
||||||
}
|
let HomeUsernameText = document.getElementsByClassName('home-title2')[0];
|
||||||
}
|
HomeUsernameText.classList.add('text-plusdx');
|
||||||
});
|
let Label = document.createElement('div');
|
||||||
|
Label.classList = 'hplusdx-banner reqFadeAnim rounded-2';
|
||||||
|
Label.setAttribute('style', 'margin-top:-8px');
|
||||||
|
Label.innerText = 'Deluxe';
|
||||||
|
HomeUsernameText.parentElement.appendChild(Label);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1,53 +1,61 @@
|
||||||
let Comments = document.getElementById('comments')
|
/*
|
||||||
const Type = window.location.pathname.split('/')[1]
|
this script will need to be updated when the new profile URLs are fully rolled out
|
||||||
|
*/
|
||||||
|
|
||||||
let CreatorID;
|
!(() => {
|
||||||
switch (Type) {
|
let Comments = document.getElementById('comments');
|
||||||
case 'store':
|
const Type = window.location.pathname.split('/')[1];
|
||||||
if (document.querySelector('h5 .text-reset[href^="/users/"]')) {
|
|
||||||
CreatorID = document.querySelector('h5 .text-reset[href^="/users/"]').getAttribute('href').split('/')[2]
|
|
||||||
} else {CreatorID = 1}
|
|
||||||
break
|
|
||||||
case 'places':
|
|
||||||
CreatorID = document.querySelector('.mcard .col .text-muted [href^="/users/"]').getAttribute('href').split('/')[2]
|
|
||||||
break
|
|
||||||
case 'feed':
|
|
||||||
CreatorID = document.querySelector('p a[href^="/users/"].text-reset').getAttribute('href').split('/')[2]
|
|
||||||
break
|
|
||||||
case 'guilds':
|
|
||||||
CreatorID = document.querySelector('[class^="userlink-"][href^="/users/"]').getAttribute('href').split('/')[2]
|
|
||||||
Comments = document.getElementById('wall-posts')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Array.from(Comments.children).forEach(element => {
|
|
||||||
LoadCreatorTag(element)
|
|
||||||
});
|
|
||||||
|
|
||||||
const Observer = new MutationObserver(function (list){
|
let CreatorID;
|
||||||
for (let record of list) {
|
if (Type === 'store') {
|
||||||
for (let element of record.addedNodes) {
|
if (document.querySelector('h5 .text-reset[href^="/users/"]')) {
|
||||||
LoadCreatorTag(element)
|
CreatorID = document.querySelector('h5 .text-reset[href^="/users/"]').getAttribute('href').split('/')[2];
|
||||||
}
|
} else {
|
||||||
}
|
CreatorID = 1;
|
||||||
});
|
}
|
||||||
Observer.observe(Comments, {attributes: false, childList: true, subtree: false})
|
} else if (Type === 'places') {
|
||||||
|
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];
|
||||||
|
} else if (Type === 'guilds') {
|
||||||
|
CreatorID = document.querySelector('[class^="userlink-"][href^="/users/"]').getAttribute('href').split('/')[2];
|
||||||
|
Comments = document.getElementById('wall-posts');
|
||||||
|
}
|
||||||
|
|
||||||
function LoadCreatorTag(element) {
|
const Observer = new MutationObserver(function (list) {
|
||||||
let NameElement;
|
for (let record of list) {
|
||||||
if (!(Type === 'guilds')) {
|
for (let element of record.addedNodes) {
|
||||||
NameElement = element.querySelector('.text-reset[href^="/users/"]')
|
if (element.classList.contains('card')) {
|
||||||
} else {
|
LoadCreatorTag(element);
|
||||||
NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]')
|
}
|
||||||
}
|
}
|
||||||
let UserID = NameElement.getAttribute('href').split('/')[2]
|
}
|
||||||
if (UserID === CreatorID) {
|
});
|
||||||
let Tag = document.createElement('span')
|
Observer.observe(Comments, {attributes: false, childList: true, subtree: false});
|
||||||
Tag.classList = 'badge bg-primary'
|
|
||||||
Tag.style.marginLeft = '5px'
|
const LoadCreatorTag = function (element) {
|
||||||
Tag.style.verticalAlign = 'text-top'
|
let NameElement = element.querySelector('.text-reset[href^="/users/"]');
|
||||||
Tag.innerText = 'CREATOR'
|
if (Type === 'guilds') {
|
||||||
NameElement.appendChild(Tag)
|
NameElement = element.querySelector('[class^="userlink-"][href^="/users/"]');
|
||||||
//console.log(window.bootstrap)
|
}
|
||||||
//new window.bootstrap.Tooltip(Tag, {toggle:"tooltip",title:"This user is the creator of this asset!"})
|
|
||||||
}
|
let UserID = NameElement.getAttribute('href').split('/')[2];
|
||||||
}
|
if (UserID === CreatorID) {
|
||||||
|
let Tag = document.createElement('span');
|
||||||
|
Tag.classList = 'badge bg-primary';
|
||||||
|
Tag.style.marginLeft = '5px';
|
||||||
|
Tag.style.verticalAlign = 'text-top';
|
||||||
|
Tag.innerText = 'CREATOR';
|
||||||
|
if (Type === 'guilds') {
|
||||||
|
Tag.innerText = 'LEADER';
|
||||||
|
}
|
||||||
|
NameElement.appendChild(Tag);
|
||||||
|
|
||||||
|
//new window.bootstrap.Tooltip(Tag, {toggle:"tooltip",title:"This user is the creator of this asset!"})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.from(Comments.children).forEach((element) => {
|
||||||
|
LoadCreatorTag(element);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
!(async () => {
|
|
||||||
const ID = window.location.pathname.split('/')[3]
|
|
||||||
const Response = await fetch('https://api.polytoria.com/v1/places/'+ID)
|
|
||||||
let Status = await Response.json()
|
|
||||||
Status = Status.isActive
|
|
||||||
console.log(Status)
|
|
||||||
|
|
||||||
const Form = document.querySelector('form[action="/create/place/update"]')
|
|
||||||
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>
|
|
||||||
</label>
|
|
||||||
<br>
|
|
||||||
`
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
ActivityBtn.addEventListener('click', function() {
|
|
||||||
fetch(`https://polytoria.com/api/places/${ID}/toggle-active`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRF-Token': document.querySelector('input[name="_csrf"]').value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok ' + response.status)
|
|
||||||
}
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
Status = data.isActive
|
|
||||||
ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate'
|
|
||||||
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success')
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})()
|
|
||||||
|
|
@ -3,43 +3,47 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
!(() => {
|
!(() => {
|
||||||
return
|
return;
|
||||||
const PlaceID = parseInt(window.location.pathname.split('/')[2])
|
const PlaceID = parseInt(window.location.pathname.split('/')[2]);
|
||||||
|
|
||||||
fetch('https://polytoria.com/home')
|
fetch('https://polytoria.com/home')
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error('Network not ok')
|
throw new Error('Network not ok');
|
||||||
}
|
}
|
||||||
return response.text()
|
return response.text();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
const Parser = new DOMParser()
|
const Parser = new DOMParser();
|
||||||
const Doc = Parser.parseFromString(data, 'text/html')
|
const Doc = Parser.parseFromString(data, 'text/html');
|
||||||
|
|
||||||
fetch('https://polytoria.com/api/places/join',{
|
fetch('https://polytoria.com/api/places/join', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-Csrf-Token': Doc.querySelector('[name="_csrf"]').value
|
'X-Csrf-Token': Doc.querySelector('[name="_csrf"]').value
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
'placeID': PlaceID
|
placeID: PlaceID
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
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.success !== true) {throw new Error(data.message)}
|
if (data.success !== true) {
|
||||||
setTimeout(function(){
|
throw new Error(data.message);
|
||||||
window.location.href = 'polytoria://client/' + data.token
|
}
|
||||||
window.location.href = 'https://polytoria.com/places/' + PlaceID
|
setTimeout(function () {
|
||||||
}, 5000)
|
window.location.href = 'polytoria://client/' + data.token;
|
||||||
})
|
window.location.href = 'https://polytoria.com/places/' + PlaceID;
|
||||||
.catch(error => {console.log(error)})
|
}, 5000);
|
||||||
})
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
737
js/places/place-view.js
Executable file → Normal file
|
|
@ -1,227 +1,387 @@
|
||||||
let URLSplit = window.location.pathname.split('/');
|
const PlaceID = parseInt(window.location.pathname.split('/')[2]);
|
||||||
let GameID = URLSplit[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;
|
||||||
|
let PlaceDetails = null;
|
||||||
|
|
||||||
var Settings;
|
var Settings;
|
||||||
let PinnedGames;
|
let TimePlayed;
|
||||||
|
var PinnedGamesData = [];
|
||||||
|
let GamePinned;
|
||||||
|
|
||||||
|
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')) || [];
|
||||||
|
|
||||||
!(() => {
|
!(() => {
|
||||||
if (GameID === undefined) {return}
|
if (PlaceID === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const DataContainer = document.getElementById('likes-data-container')
|
const DataContainer = document.getElementById('likes-data-container');
|
||||||
const RatingsData = {
|
const RatingsData = {
|
||||||
Likes: parseInt(DataContainer.getAttribute('data-like-count')),
|
Likes: parseInt(DataContainer.getAttribute('data-like-count')),
|
||||||
Dislikes: parseInt(DataContainer.getAttribute('data-dislike-count')),
|
Dislikes: parseInt(DataContainer.getAttribute('data-dislike-count')),
|
||||||
Percentage: null
|
Percentage: null
|
||||||
}
|
};
|
||||||
RatingsData.Percentage = Math.floor((RatingsData.Likes / (RatingsData.Likes + RatingsData.Dislikes)) * 100)
|
RatingsData.Percentage = Math.floor((RatingsData.Likes / (RatingsData.Likes + RatingsData.Dislikes)) * 100);
|
||||||
const RatingsContainer = document.getElementById('thumbup-btn').parentElement.parentElement
|
const RatingsContainer = document.getElementById('thumbup-btn').parentElement.parentElement;
|
||||||
|
|
||||||
const PercentageLabel = document.createElement('small')
|
const PercentageLabel = document.createElement('small');
|
||||||
PercentageLabel.classList = 'text-muted'
|
PercentageLabel.classList = 'text-muted';
|
||||||
PercentageLabel.style.fontSize = '0.8rem'
|
PercentageLabel.style.fontSize = '0.8rem';
|
||||||
PercentageLabel.style.marginLeft = '10px'
|
PercentageLabel.style.marginLeft = '10px';
|
||||||
PercentageLabel.style.marginRight = '10px'
|
PercentageLabel.style.marginRight = '10px';
|
||||||
PercentageLabel.innerText = RatingsData.Percentage + '%'
|
|
||||||
|
|
||||||
RatingsContainer.children[0].appendChild(PercentageLabel)
|
if (!isNaN(RatingsData.Percentage)) {
|
||||||
|
PercentageLabel.innerText = RatingsData.Percentage + '%';
|
||||||
|
} else {
|
||||||
|
PercentageLabel.innerText = 'N/A';
|
||||||
|
}
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
RatingsContainer.children[0].appendChild(PercentageLabel);
|
||||||
Settings = result.PolyPlus_Settings;
|
|
||||||
|
|
||||||
if (Settings.PinnedGamesOn === true) {
|
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_TimePlayed'], async function (result) {
|
||||||
HandlePinnedGames()
|
Settings = result.PolyPlus_Settings || {};
|
||||||
}
|
TimePlayed = result.PolyPlus_TimePlayed || {};
|
||||||
|
|
||||||
// Disabled settings
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
if (Settings.InlineEditingOn === true || 1 === 2) {
|
Utilities = Utilities.default;
|
||||||
HandleInlineEditing()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.GameProfilesOn === true && 1 === 2) {
|
if (Settings.PinnedGamesOn === true) {
|
||||||
HandleGameProfiles()
|
PinnedGames(result.PolyPlus_PinnedGames);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
})()
|
|
||||||
|
|
||||||
async function HandlePinnedGames() {
|
if (Settings.InlineEditingOn === true && GameCreator === UserID) {
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result){
|
InlineEditing();
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
}
|
||||||
const PinBtn = document.createElement('button');
|
|
||||||
PinBtn.classList = 'btn btn-warning btn-sm';
|
|
||||||
PinBtn.style = 'position: absolute; right: 0; margin-right: 7px;'
|
|
||||||
|
|
||||||
if (PinnedGames.includes(parseInt(GameID))) {
|
const Description = document.querySelector('.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small');
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
if (Settings.GameProfilesOn === true && Description !== null) {
|
||||||
} else {
|
const GameProfileRegex = /p\+gp;(#(?:[A-Fa-f0-9]{3}){1,2}\b(;#(?:[A-Fa-f0-9]{3}){1,2}\b)+)/gm;
|
||||||
if (PinnedGames.length !== 5) {
|
if (GameProfileRegex.test(Description.innerText)) {
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
|
const Info = GameProfileRegex.exec(Description.innerText)[1].split(';');
|
||||||
} else {
|
GameProfile(Info);
|
||||||
PinBtn.setAttribute('disabled', true)
|
}
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin (max 5/5)'
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PinBtn.addEventListener('click', function() {
|
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
PinBtn.setAttribute('disabled', 'true')
|
IRLPrice();
|
||||||
|
}
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result) {
|
if (Settings.TimePlayedOn === true) {
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
const TimePlayedNameRow = document.createElement('li');
|
||||||
const Index = PinnedGames.indexOf(parseInt(GameID));
|
TimePlayedNameRow.innerText = 'Time Played:';
|
||||||
if (Index !== -1) {
|
|
||||||
PinnedGames.splice(Index, 1);
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
|
|
||||||
} else {
|
|
||||||
PinnedGames.push(parseInt(GameID));
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': PinnedGames, arrayOrder: true }, function() {
|
const TimePlayedValueRow = document.createElement('li')
|
||||||
setTimeout(function() {
|
if (TimePlayed[PlaceID]) {
|
||||||
PinBtn.removeAttribute('disabled')
|
TimePlayedValueRow.innerHTML = '<i class="text-center text-muted fa-duotone fa-solid fa-watch me-1" style="width: 1.3em;"></i> ' + new Date(TimePlayed[PlaceID] * 1000).toISOString().slice(11, 19) + ' <small style="font-size: 0.7rem;" class="text-muted">(poly+)</small>'
|
||||||
}, 1250)
|
} else {
|
||||||
});
|
TimePlayedValueRow.innerHTML = '<i class="text-center text-muted fa-duotone fa-solid fa-watch me-1" style="width: 1.3em;"></i> - <small style="font-size: 0.7rem;" class="text-muted">(poly+)</small>'
|
||||||
});
|
}
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll('.card-header')[2].appendChild(PinBtn);
|
InfoColumns[0].appendChild(TimePlayedNameRow);
|
||||||
|
InfoColumns[1].appendChild(TimePlayedValueRow);
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener(function(changes, namespace) {
|
if (document.getElementById('btn-play')) {
|
||||||
if ('PolyPlus_PinnedGames' in changes) {
|
document.getElementById('btn-play').addEventListener('click', function(){
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result) {
|
chrome.runtime.sendMessage({ action: "start_time_played", placeID: PlaceID, userID: UserID });
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
})
|
||||||
|
|
||||||
if (PinnedGames.includes(parseInt(GameID))) {
|
Array.from(document.querySelectorAll('button[onclick^="joinPlace"]')).forEach(serverJoin => {
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
serverJoin.addEventListener("click", function(){
|
||||||
} else {
|
chrome.runtime.sendMessage({ action: "start_time_played", placeID: PlaceID, userID: UserID })
|
||||||
if (PinnedGames.length !== 5) {
|
})
|
||||||
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 5/5)'
|
if (Settings.ShowPlaceRevenueOn === true) {
|
||||||
}
|
const NameRow = document.createElement('li');
|
||||||
}
|
NameRow.innerText = 'Revenue:';
|
||||||
});
|
|
||||||
}
|
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);
|
||||||
|
|
||||||
|
let Calculating = false;
|
||||||
|
CalculateRevenueButton.addEventListener('click', function () {
|
||||||
|
if (Calculating === false) {
|
||||||
|
Calculating = true;
|
||||||
|
CalculateRevenueButton.innerText = '$ Calculating...';
|
||||||
|
PlaceRevenue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedAchievements && Settings.ImprovedAchievements.Enabled === true && AchievementsTab.getElementsByClassName('display-3')[0] === undefined) {
|
||||||
|
if (Settings.ImprovedAchievements.ProgressBarOn && Settings.ImprovedAchievements.ProgressBarOn === true) {
|
||||||
|
AchievementProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedAchievements.PercentageOn && Settings.ImprovedAchievements.PercentageOn === true) {
|
||||||
|
AchievementEarnedPercentage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ImprovedAchievements.OpacityOn && Settings.ImprovedAchievements.OpacityOn === true) {
|
||||||
|
for (let achievement of Achievements) {
|
||||||
|
if ((achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined) === false) {
|
||||||
|
achievement.style.opacity = '0.5';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.ReaddCopyablePlacesOn === true) {
|
||||||
|
ReaddCopyable()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.querySelector('.text-warning .fa-lock') || new URLSearchParams(window.location.search).has('testRestrictedServers')) {
|
||||||
|
const ServerJoinButtons = Array.from(document.querySelectorAll('#servers-tabpane button'));
|
||||||
|
for (let button of ServerJoinButtons) {
|
||||||
|
button.classList.add('btn-secondary');
|
||||||
|
button.classList.remove('btn-success');
|
||||||
|
button.disabled = true;
|
||||||
|
button.innerText = 'Restricted'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
function PinnedGames(placeIDs) {
|
||||||
|
const PinButton = document.createElement('button');
|
||||||
|
PinButton.classList = 'btn btn-primary btn-sm';
|
||||||
|
PinButton.style = 'position: absolute; top: 0; right: 0; margin: 4px; font-size: 1.3em;';
|
||||||
|
PinButton.innerHTML = `
|
||||||
|
<i class="fa-regular fa-star"></i>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const UpdatePinButtonState = function() {
|
||||||
|
PinButton.classList = 'btn btn-primary btn-sm';
|
||||||
|
PinButton.disabled = false; // Ensure button is enabled initially
|
||||||
|
if (placeIDs.indexOf(PlaceID) === -1) {
|
||||||
|
// Not Pinned
|
||||||
|
if (placeIDs.length >= Utilities.Limits.PinnedGames) {
|
||||||
|
PinButton.disabled = true;
|
||||||
|
}
|
||||||
|
PinButton.children[0].classList = 'fa-regular fa-star';
|
||||||
|
} else {
|
||||||
|
// Pinned
|
||||||
|
PinButton.children[0].classList = 'fa-duotone fa-star';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PinButton.addEventListener('mouseenter', function() {
|
||||||
|
if (placeIDs.indexOf(PlaceID) !== -1) {
|
||||||
|
PinButton.classList.add('btn-danger');
|
||||||
|
PinButton.classList.remove('btn-primary');
|
||||||
|
PinButton.children[0].classList.add('fa-star-half-stroke');
|
||||||
|
PinButton.children[0].classList.remove('fa-star');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
PinButton.addEventListener('mouseleave', function() {
|
||||||
|
if (placeIDs.indexOf(PlaceID) !== -1) {
|
||||||
|
PinButton.classList.add('btn-primary');
|
||||||
|
PinButton.classList.remove('btn-danger');
|
||||||
|
PinButton.children[0].classList.add('fa-star');
|
||||||
|
PinButton.children[0].classList.remove('fa-star-half-stroke');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
UpdatePinButtonState();
|
||||||
|
document.querySelector('h1.my-0').parentElement.appendChild(PinButton);
|
||||||
|
|
||||||
|
PinButton.addEventListener('click', function() {
|
||||||
|
if (placeIDs.indexOf(PlaceID) === -1) {
|
||||||
|
placeIDs.push(PlaceID);
|
||||||
|
} else {
|
||||||
|
placeIDs.splice(placeIDs.indexOf(PlaceID), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear cache
|
||||||
|
chrome.storage.local.set({'PolyPlus_PinnedGamesData':{
|
||||||
|
data: undefined,
|
||||||
|
requested: 0
|
||||||
|
}}, function(){});
|
||||||
|
|
||||||
|
UpdatePinButtonState();
|
||||||
|
|
||||||
|
chrome.storage.sync.set({'PolyPlus_PinnedGames': placeIDs}, function() {
|
||||||
|
PinButton.disabled = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
PinButton.disabled = false;
|
||||||
|
UpdatePinButtonState(); // Ensure state is updated after re-enabling
|
||||||
|
}, 750);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
chrome.storage.onChanged.addListener(function(changes) {
|
||||||
|
if ('PolyPlus_PinnedGames' in changes) {
|
||||||
|
placeIDs = changes.PolyPlus_PinnedGames.newValue;
|
||||||
|
UpdatePinButtonState();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function HandleInlineEditing() {
|
async function InlineEditing() {
|
||||||
// Fix description editing
|
/*
|
||||||
// Make it possible to edit description even if the game doesn't initially have a description
|
INLINE EDITING TO-DO:
|
||||||
// Add the ability to edit the game's genre
|
- Make it possible to edit the description even if there is no description initially
|
||||||
// Improve editing visuals overall
|
- Make it possible to edit the place's genre
|
||||||
|
|
||||||
let Editing = false
|
|
||||||
|
|
||||||
const PlaceTitle = document.querySelector('.card-header h1[style="font-weight:800;font-size:1.6em"]')
|
|
||||||
const PlaceTitleSpan = document.createElement('span')
|
|
||||||
PlaceTitleSpan.innerText = PlaceTitle.innerText
|
|
||||||
PlaceTitle.innerHTML = ''
|
|
||||||
PlaceTitle.appendChild(PlaceTitleSpan)
|
|
||||||
|
|
||||||
const PlaceDesc = document.querySelector('.card.m-card.mb-2 card-body.p-3.small')
|
|
||||||
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"
|
|
||||||
]
|
|
||||||
|
|
||||||
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</span>'
|
|
||||||
document.querySelectorAll('.card-header')[3].appendChild(EditBtn);
|
|
||||||
/*
|
|
||||||
const EditBtn = document.createElement('button')
|
|
||||||
EditBtn.classList = 'text-muted'
|
|
||||||
EditBtn.innerHTML = `
|
|
||||||
<i class="fa-duotone fa-hammer"></i>
|
|
||||||
`
|
|
||||||
EditBtn.setAttribute('style', 'background: transparent; border: none; font-size: 1rem; vertical-align: middle;')
|
|
||||||
PlaceTitle.appendChild(EditBtn)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EditBtn.addEventListener('click', function(){
|
let Editing = false;
|
||||||
Editing = (Editing === true) ? false : true
|
|
||||||
|
|
||||||
EditBtn.children[0].classList.toggle('fa-hammer')
|
const Style = document.createElement('style');
|
||||||
EditBtn.children[0].classList.toggle('fa-check-double')
|
Style.innerHTML = `
|
||||||
EditBtn.children[0].classList.toggle('fa-fade')
|
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-visible {display: block !important;}
|
||||||
|
.polyplus-inlineEditing-visible {display: none;}
|
||||||
|
|
||||||
PlaceTitleSpan.setAttribute('contenteditable', Editing.toString())
|
body[data-polyplus-inlineEditing="true"] .polyplus-inlineEditing-hidden {display: none !important;}
|
||||||
if (PlaceDesc !== null) {
|
.polyplus-inlineEditing-hidden {display: block;}
|
||||||
console.log('Description exists')
|
`;
|
||||||
PlaceDesc.setAttribute('contenteditable', Editing.toString())
|
document.body.prepend(Style);
|
||||||
}
|
|
||||||
if (Editing === false) {
|
|
||||||
const Send = new FormData()
|
|
||||||
Send.append("_csrf", document.querySelector('input[name="_csrf"]').value)
|
|
||||||
Send.append("id", GameID)
|
|
||||||
Send.append("name", PlaceTitle.innerText || '')
|
|
||||||
|
|
||||||
fetch('/create/place/update', {method:"POST",body:Send})
|
const Inputs = [
|
||||||
.then(response => {
|
{
|
||||||
if (!response.ok) {
|
name: 'name',
|
||||||
throw new Error('Network not ok')
|
element: null,
|
||||||
}
|
reference: '.card-header h1[style="font-weight:800;font-size:1.6em"]',
|
||||||
return response.text()
|
placeholder: 'Place Title..',
|
||||||
})
|
required: true,
|
||||||
.then(data => {
|
isTextarea: false,
|
||||||
console.log('Successfully edited game')
|
styles: 'font-weight:800;font-size:1.6em'
|
||||||
})
|
},
|
||||||
.catch(error => {
|
{
|
||||||
console.log('Error while editing game')
|
name: 'description',
|
||||||
});
|
element: null,
|
||||||
}
|
reference: '.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small',
|
||||||
});
|
placeholder: 'Place Description..',
|
||||||
|
required: false,
|
||||||
|
isTextarea: true,
|
||||||
|
styles: 'height:300px; overflow-y:auto;'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
console.log(Inputs);
|
||||||
|
for (let input of Inputs) {
|
||||||
|
let Input = input.isTextarea === true ? document.createElement('textarea') : document.createElement('input');
|
||||||
|
input.element = Input;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Reference.classList.add('polyplus-inlineEditing-hidden');
|
||||||
|
Reference.parentElement.appendChild(Input);
|
||||||
|
}
|
||||||
|
|
||||||
|
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'
|
||||||
|
];
|
||||||
|
|
||||||
|
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>';
|
||||||
|
document.getElementsByClassName('card-header')[3].appendChild(EditBtn);
|
||||||
|
|
||||||
|
EditBtn.addEventListener('click', function () {
|
||||||
|
Editing = !Editing;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (Editing === false) {
|
||||||
|
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('after');
|
||||||
|
fetch('/create/place/update', {method: 'POST', body: Send})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network not ok');
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
console.log('Successfully edited game');
|
||||||
|
for (let input of Inputs) {
|
||||||
|
const Reference = document.querySelector(input.reference);
|
||||||
|
Reference.innerText = input.element.value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
alert('Error while saving changes');
|
||||||
|
console.log('Error while editing game');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const Data = JSON.parse('{"gameTitle": "Hyper[Fart]","bg": "#000","accent": "#007bff","secondary": "#","cardBg": "#313131","font": "","text": "#fff"}')
|
async function GameProfile(data) {
|
||||||
|
document.querySelector('h1.my-0').setAttribute('game-key', 'true');
|
||||||
|
document.querySelector('div[style="min-height: 60vh;"]').id = 'gameprofile';
|
||||||
|
|
||||||
async function HandleGameProfiles(Data) {
|
const Style = document.createElement('style');
|
||||||
document.querySelector('h1.my-0')
|
|
||||||
.setAttribute('game-key', 'true');
|
|
||||||
document.querySelector('div[style="min-height: 60vh;"]')
|
|
||||||
.id = 'gameprofile';
|
|
||||||
|
|
||||||
const Style = document.createElement('style')
|
Style.innerHTML = `
|
||||||
|
|
||||||
Style.innerHTML = `
|
|
||||||
div#app {
|
div#app {
|
||||||
background: ${Data.bg} !important;
|
background: ${data[0]} !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gameprofile {
|
#gameprofile {
|
||||||
/*font-family: ${Data.font} !important;*/
|
/*font-family: no !important;*/
|
||||||
color: ${Data.text} !important;
|
color: ${data[4]} !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gameprofile .card {
|
#gameprofile .card {
|
||||||
--bs-card-bg: ${Data.cardBg};
|
--bs-card-bg: ${data[3]};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -232,11 +392,208 @@ async function HandleGameProfiles(Data) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#gameprofile .card.mcard [game-key] {
|
#gameprofile .card.mcard [game-key] {
|
||||||
background: linear-gradient(to bottom, ${Data.accent}, ${Data.secondary});
|
background: linear-gradient(to bottom, ${data[1]}, ${data[2]});
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-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;
|
||||||
|
for (let gamepass of Gamepasses) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PlaceRevenue() {
|
||||||
|
const BricksPerView = 5;
|
||||||
|
|
||||||
|
if (PlaceDetails === null) {
|
||||||
|
PlaceDetails = (await (await fetch('https://api.polytoria.com/v1/places/' + PlaceID)).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 CreatorTax = 0.35;
|
||||||
|
switch (CreatorDetails.membershipType) {
|
||||||
|
case 'plus':
|
||||||
|
CreatorTax = 0.25;
|
||||||
|
break;
|
||||||
|
case 'plusDeluxe':
|
||||||
|
CreatorTax = 0.15;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
for (let gamepass of Gamepasses.gamepasses) {
|
||||||
|
const PriceAfterTax = Math.floor(gamepass.asset.price - gamepass.asset.price * CreatorTax);
|
||||||
|
Revenue += PriceAfterTax * gamepass.asset.sales;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
let AchievementCost = 0
|
||||||
|
let FreeAchievements = null;
|
||||||
|
for (let achievement of Achievements.achievements) {
|
||||||
|
// decrease total by price of achievement creation based on when the achievement was created
|
||||||
|
|
||||||
|
if ()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (let achievement of Achievements) {
|
||||||
|
Achieved = achievement.getElementsByClassName('fad fa-check-circle')[0] !== undefined;
|
||||||
|
|
||||||
|
if (Achieved === true) {
|
||||||
|
AchievementsEarned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PercentageEarned = ((AchievementsEarned * 100) / AchievementCount).toFixed(0);
|
||||||
|
|
||||||
|
const ProgressBar = document.createElement('div');
|
||||||
|
ProgressBar.role = 'progressbar';
|
||||||
|
ProgressBar.classList = 'progress';
|
||||||
|
ProgressBar.style.background = '#000';
|
||||||
|
ProgressBar.ariaValueNow = PercentageEarned;
|
||||||
|
ProgressBar.ariaValueMin = '0';
|
||||||
|
ProgressBar.ariaValueMax = '100';
|
||||||
|
ProgressBar.innerHTML = `<div class="progress-bar progress-bar-striped text-bg-warning" style="width: ${PercentageEarned}%">${PercentageEarned}%</div>`;
|
||||||
|
|
||||||
|
AchievementsTab.prepend(document.createElement('hr'));
|
||||||
|
AchievementsTab.prepend(ProgressBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function AchievementEarnedPercentage() {
|
||||||
|
if (PlaceDetails === null) {
|
||||||
|
PlaceDetails = (await (await fetch('https://api.polytoria.com/v1/places/' + PlaceID)).json());
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetAchievementDifficulty = function(percent) {
|
||||||
|
if (percent >= 90 && percent <= 100) {
|
||||||
|
return 'Freebie';
|
||||||
|
} else if (percent >= 80 && percent <= 89.9) {
|
||||||
|
return 'Cake Walk';
|
||||||
|
} else if (percent >= 50 && percent <= 79.9) {
|
||||||
|
return 'Easy';
|
||||||
|
} else if (percent >= 30 && percent <= 49.9) {
|
||||||
|
return 'Moderate';
|
||||||
|
} else if (percent >= 20 && percent <= 29.9) {
|
||||||
|
return 'Challenging';
|
||||||
|
} else if (percent >= 10 && percent <= 19.9) {
|
||||||
|
return 'Hard';
|
||||||
|
} else if (percent >= 5 && percent <= 9.9) {
|
||||||
|
return 'Extreme';
|
||||||
|
} else if (percent >= 1 && percent <= 4.9) {
|
||||||
|
return 'Insane';
|
||||||
|
} else if (percent >= 0 && percent <= 0.9) {
|
||||||
|
return 'Impossible';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserCount = PlaceDetails.uniqueVisits;
|
||||||
|
for (let achievement of Achievements) {
|
||||||
|
const OwnerText = achievement.getElementsByClassName('text-muted small my-0')[0];
|
||||||
|
// thanks to Stackoverflow on how to remove everything except numbers from string
|
||||||
|
const OwnerCount = parseInt(OwnerText.innerText.replace(/[^0-9]/g, ''));
|
||||||
|
const PercentageOfPlayers = ((OwnerCount * 100) / UserCount).toFixed(2);
|
||||||
|
|
||||||
|
OwnerText.innerHTML += ' (' + PercentageOfPlayers + '%, ' + GetAchievementDifficulty(PercentageOfPlayers) + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ReaddCopyable() {
|
||||||
|
if (PlaceDetails === null) {
|
||||||
|
PlaceDetails = (await (await fetch('https://api.polytoria.com/v1/places/' + PlaceID)).json());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlaceDetails.isCopyable) {
|
||||||
|
const TitleCardButtons = document.querySelector('.card:has(h1.my-0) .col-auto[style^="m"]')
|
||||||
|
|
||||||
|
const DownloadCopyButton = document.createElement('button')
|
||||||
|
DownloadCopyButton.style.padding = '9px'
|
||||||
|
DownloadCopyButton.classList = 'px-4 btn btn-success my-2'
|
||||||
|
DownloadCopyButton.setAttribute('data-bs-toggle', 'tooltip')
|
||||||
|
DownloadCopyButton.setAttribute('data-bs-title', 'Download this place')
|
||||||
|
DownloadCopyButton.innerHTML = '<i class="fas fa-download"></i>'
|
||||||
|
|
||||||
|
if (TitleCardButtons.children[0].children.length === 0) {
|
||||||
|
TitleCardButtons.children[0].innerHTML = '<div class="col-auto px-1"></div>'
|
||||||
|
TitleCardButtons.children[0].appendChild(DownloadCopyButton)
|
||||||
|
} else {
|
||||||
|
TitleCardButtons.children[0].prepend(DownloadCopyButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadCopyButton.addEventListener('click', async function () {
|
||||||
|
let CreatorToken = (await (await fetch('https://polytoria.com/api/places/edit', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({placeID: PlaceID})
|
||||||
|
})).json()).token;
|
||||||
|
|
||||||
|
fetch(`https://api.polytoria.com/v1/places/get-place?id=${PlaceID}&tokenType=creator`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: CreatorToken
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network not ok');
|
||||||
|
}
|
||||||
|
return response.blob();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
const DownloadURL = URL.createObjectURL(data);
|
||||||
|
|
||||||
|
const Link = document.createElement('a');
|
||||||
|
Link.href = DownloadURL;
|
||||||
|
Link.download = PlaceDetails.name + '.poly';
|
||||||
|
document.body.appendChild(Link);
|
||||||
|
Link.click();
|
||||||
|
Link.remove();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,360 +0,0 @@
|
||||||
let GameID = window.location.pathname.split('/')[2]
|
|
||||||
|
|
||||||
var Settings;
|
|
||||||
let PinnedGames;
|
|
||||||
let GamePinned;
|
|
||||||
|
|
||||||
!(() => {
|
|
||||||
if (GameID === undefined) {return}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
const PercentageLabel = document.createElement('small')
|
|
||||||
PercentageLabel.classList = 'text-muted'
|
|
||||||
PercentageLabel.style.fontSize = '0.8rem'
|
|
||||||
PercentageLabel.style.marginLeft = '10px'
|
|
||||||
PercentageLabel.style.marginRight = '10px'
|
|
||||||
PercentageLabel.innerText = RatingsData.Percentage + '%'
|
|
||||||
|
|
||||||
RatingsContainer.children[0].appendChild(PercentageLabel)
|
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
|
||||||
Settings = result.PolyPlus_Settings || {
|
|
||||||
PinnedGamesOn: true,
|
|
||||||
InlineEditingOn: false,
|
|
||||||
GameProfilesOn: false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Settings.PinnedGamesOn === true) {
|
|
||||||
HandlePinnedGames()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Work in Progress
|
|
||||||
if (Settings.InlineEditingOn === true) {
|
|
||||||
HandleInlineEditing()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Work in Progress
|
|
||||||
if (Settings.GameProfilesOn === true) {
|
|
||||||
HandleGameProfiles()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})()
|
|
||||||
|
|
||||||
async function HandlePinnedGames() {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result){
|
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || {};
|
|
||||||
/*
|
|
||||||
const PinBtn = document.createElement('button');
|
|
||||||
PinBtn.classList = 'btn btn-warning btn-sm';
|
|
||||||
PinBtn.style = 'position: absolute; right: 0; margin-right: 7px;'
|
|
||||||
|
|
||||||
if (PinnedGames[GameID]) {
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
|
||||||
} else {
|
|
||||||
if (PinnedGames.length !== 5) {
|
|
||||||
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 5/5)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
const PinBtn = document.createElement('button');
|
|
||||||
PinBtn.classList = 'btn btn-warning btn-sm';
|
|
||||||
PinBtn.style = 'position: absolute; right: 0; margin-right: 7px;'
|
|
||||||
|
|
||||||
if (PinnedGames.includes(parseInt(GameID))) {
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
|
||||||
} else {
|
|
||||||
if (PinnedGames.length !== 5) {
|
|
||||||
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 5/5)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PinBtn.addEventListener('click', function() {
|
|
||||||
PinBtn.setAttribute('disabled', 'true')
|
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result) {
|
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
|
||||||
/*
|
|
||||||
const Index = PinnedGames.indexOf(parseInt(GameID))
|
|
||||||
if (Index !== -1) {
|
|
||||||
//delete PinnedGames[GameID]
|
|
||||||
PinnedGames.splice(Index, 1)
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
|
|
||||||
} else {
|
|
||||||
//PinnedGames[GameID] = {lastVisited: new Date()}
|
|
||||||
PinnedGames.push(parseInt(GameID))
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
const Index = PinnedGames.indexOf(parseInt(GameID));
|
|
||||||
if (Index !== -1) {
|
|
||||||
PinnedGames.splice(Index, 1);
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
|
|
||||||
} else {
|
|
||||||
PinnedGames.push(parseInt(GameID));
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_PinnedGames': PinnedGames, arrayOrder: true }, function() {
|
|
||||||
setTimeout(function() {
|
|
||||||
PinBtn.removeAttribute('disabled')
|
|
||||||
console.log(PinnedGames)
|
|
||||||
}, 1250)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementsByClassName('card-header')[2].appendChild(PinBtn);
|
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener(function(changes, namespace) {
|
|
||||||
if ('PolyPlus_PinnedGames' in changes) {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function(result) {
|
|
||||||
PinnedGames = result.PolyPlus_PinnedGames || [];
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (PinnedGames[GameID]) {
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
|
||||||
} else {
|
|
||||||
if (PinnedGames.length !== 5) {
|
|
||||||
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 5/5)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (PinnedGames.includes(parseInt(GameID))) {
|
|
||||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
|
||||||
} else {
|
|
||||||
if (PinnedGames.length !== 5) {
|
|
||||||
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 5/5)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function HandleInlineEditing() {
|
|
||||||
// Fix description editing
|
|
||||||
// Make it possible to edit description even if the game doesn't initially have a description
|
|
||||||
// Add the ability to edit the game's genre
|
|
||||||
// Improve editing visuals overall
|
|
||||||
|
|
||||||
const GameCreator = document.querySelector('#main-content .card-body .col div.text-muted a[href^="/users/"]').getAttribute('href').split('/')[2]
|
|
||||||
console.log(GameCreator)
|
|
||||||
console.log(JSON.parse(window.localStorage.getItem('account_info')).ID)
|
|
||||||
if (GameCreator !== JSON.parse(window.localStorage.getItem('account_info')).ID) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let Editing = false
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
const Inputs = [
|
|
||||||
{
|
|
||||||
name: "name",
|
|
||||||
element: null,
|
|
||||||
reference: '.card-header h1[style="font-weight:800;font-size:1.6em"]',
|
|
||||||
placeholder: "Place Title..",
|
|
||||||
required: true,
|
|
||||||
isTextarea: false,
|
|
||||||
styles: 'font-weight:800;font-size:1.6em'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "description",
|
|
||||||
element: null,
|
|
||||||
reference: '.col:has(#likes-data-container) .card.mcard.mb-2 .card-body.p-3.small',
|
|
||||||
placeholder: "Place Description..",
|
|
||||||
required: false,
|
|
||||||
isTextarea: true,
|
|
||||||
styles: 'height:300px; overflow-y:auto;'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
console.log(Inputs)
|
|
||||||
for (let input of Inputs) {
|
|
||||||
let Input = (input.isTextarea === true) ? document.createElement('textarea') : document.createElement('input')
|
|
||||||
input.element = Input
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Reference.classList.add('polyplus-inlineEditing-hidden')
|
|
||||||
Reference.parentElement.appendChild(Input)
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
|
||||||
]
|
|
||||||
|
|
||||||
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>'
|
|
||||||
document.getElementsByClassName('card-header')[3].appendChild(EditBtn);
|
|
||||||
|
|
||||||
EditBtn.addEventListener('click', function(){
|
|
||||||
Editing = !Editing
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
if (Editing === false) {
|
|
||||||
const Send = new FormData()
|
|
||||||
Send.append("_csrf", document.querySelector('input[name="_csrf"]').value)
|
|
||||||
Send.append("id", GameID)
|
|
||||||
for (let input of Inputs) {
|
|
||||||
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 => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok')
|
|
||||||
}
|
|
||||||
return response.text()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log('Successfully edited game')
|
|
||||||
for (let input of Inputs) {
|
|
||||||
const Reference = document.querySelector(input.reference)
|
|
||||||
Reference.innerText = input.element.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
alert('Error while saving changes')
|
|
||||||
console.log('Error while editing game')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
PlaceTitleSpan.setAttribute('contenteditable', Editing.toString())
|
|
||||||
if (PlaceDesc !== null) {
|
|
||||||
console.log('Description exists')
|
|
||||||
PlaceDesc.setAttribute('contenteditable', Editing.toString())
|
|
||||||
}
|
|
||||||
if (Editing === false) {
|
|
||||||
const Send = new FormData()
|
|
||||||
Send.append("_csrf", document.querySelector('input[name="_csrf"]').value)
|
|
||||||
Send.append("id", GameID)
|
|
||||||
Send.append("name", PlaceTitle.innerText || '')
|
|
||||||
|
|
||||||
fetch('/create/place/update', {method:"POST",body:Send})
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok')
|
|
||||||
}
|
|
||||||
return response.text()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log('Successfully edited game')
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log('Error while editing game')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const Data = JSON.parse('{"gameTitle": "Hyper[Fart]","bg": "#000","accent": "#007bff","secondary": "#","cardBg": "#313131","font": "","text": "#fff"}')
|
|
||||||
|
|
||||||
async function HandleGameProfiles(Data) {
|
|
||||||
document.querySelector('h1.my-0')
|
|
||||||
.setAttribute('game-key', 'true');
|
|
||||||
document.querySelector('div[style="min-height: 60vh;"]')
|
|
||||||
.id = 'gameprofile';
|
|
||||||
|
|
||||||
const Style = document.createElement('style')
|
|
||||||
|
|
||||||
Style.innerHTML = `
|
|
||||||
div#app {
|
|
||||||
background: ${Data.bg} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gameprofile {
|
|
||||||
/*font-family: ${Data.font} !important;*/
|
|
||||||
color: ${Data.text} !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#gameprofile .card {
|
|
||||||
--bs-card-bg: ${Data.cardBg};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#gameprofile .card.mcard[game-key] .card-header {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#gameprofile .card.mcard [game-key] {
|
|
||||||
background: linear-gradient(to bottom, ${Data.accent}, ${Data.secondary});
|
|
||||||
background-clip: text;
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
document.body.appendChild(Style)
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
const InExtensionSettings = (window.location.pathname.split('/')[3] === "polyplus")
|
|
||||||
if (InExtensionSettings === true) {
|
|
||||||
window.location.href = chrome.runtime.getURL('settings.html')
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function(){
|
|
||||||
const Nav = document.getElementsByClassName('nav nav-pills')[0]
|
|
||||||
|
|
||||||
if (InExtensionSettings === true) {
|
|
||||||
Array.from(Nav.children).forEach(item => {
|
|
||||||
if (item.classList.contains('active')) {
|
|
||||||
item.classList.remove('active')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const PolyPlusItem = document.createElement('a')
|
|
||||||
PolyPlusItem.classList = 'nav-link'
|
|
||||||
PolyPlusItem.href = chrome.runtime.getURL('settings.html')
|
|
||||||
PolyPlusItem.innerHTML = `
|
|
||||||
<i class="fa-regular fa-sparkles me-1"></i> <span class="pilltitle">Poly+</span>
|
|
||||||
`
|
|
||||||
|
|
||||||
Nav.insertBefore(PolyPlusItem, Nav.getElementsByTagName('hr')[0])
|
|
||||||
});
|
|
||||||
|
|
@ -1,300 +0,0 @@
|
||||||
const 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]
|
|
||||||
|
|
||||||
var Settings;
|
|
||||||
var BestFriends;
|
|
||||||
let FavoriteBtn;
|
|
||||||
let CalculateButton;
|
|
||||||
|
|
||||||
if (UserID) {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
|
||||||
Settings = result.PolyPlus_Settings || {
|
|
||||||
IRLPriceWithCurrencyOn: false,
|
|
||||||
BestFriendsOn: false,
|
|
||||||
OutfitCostOn: true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.IRLPriceWithCurrencyOn === true) {
|
|
||||||
HandleIRLPrice()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.BestFriendsOn === true) {
|
|
||||||
HandleBestFriends()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings.OutfitCostOn === true) {
|
|
||||||
CalculateButton = document.createElement('button')
|
|
||||||
CalculateButton.classList = 'btn btn-warning btn-sm'
|
|
||||||
CalculateButton.innerText = 'Calculate Avatar Cost'
|
|
||||||
AvatarRow.parentElement.parentElement.prepend(CalculateButton)
|
|
||||||
AvatarRow.parentElement.style.marginTop = '10px'
|
|
||||||
|
|
||||||
CalculateButton.addEventListener('click', function(){
|
|
||||||
HandleOufitCost()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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.classList.remove('text-danger')
|
|
||||||
CopyItem.classList.add('text-primary')
|
|
||||||
CopyItem.href = '#'
|
|
||||||
CopyItem.innerHTML = `
|
|
||||||
<i class="fa-duotone fa-book"></i>
|
|
||||||
Copy 3D Avatar URL
|
|
||||||
`
|
|
||||||
DropdownMenu.appendChild(CopyItem)
|
|
||||||
CopyItem.addEventListener('click', function(){
|
|
||||||
navigator.clipboard.writeText(AvatarIFrame.src)
|
|
||||||
.then(() => {
|
|
||||||
alert('Successfully copied 3D avatar URL!')
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
alert('Failure to copy 3D avatar URL.')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
Way overcomplicated code when there is literally an iframe on the page with the exact same result
|
|
||||||
|
|
||||||
const UserID = window.location.pathname.split('/')[2]
|
|
||||||
const DefaultAvatar = {
|
|
||||||
"useCharacter": true,
|
|
||||||
"items": [],
|
|
||||||
"shirt": null,
|
|
||||||
"pants": null,
|
|
||||||
"tool": null,
|
|
||||||
"headColor": "#111111",
|
|
||||||
"torsoColor": "#111111",
|
|
||||||
"leftArmColor": "#111111",
|
|
||||||
"rightArmColor": "#111111",
|
|
||||||
"leftLegColor": "#111111",
|
|
||||||
"rightLegColor": "#111111",
|
|
||||||
"face": "https://c0.ptacdn.com/static/3dview/DefaultFace.png"
|
|
||||||
}
|
|
||||||
const Avatar = structuredClone(DefaultAvatar)
|
|
||||||
|
|
||||||
const Original = document.querySelector('.container .dropdown-item:nth-child(2)')
|
|
||||||
const Clone = Original.cloneNode(true)
|
|
||||||
Clone.classList.remove('text-danger')
|
|
||||||
Clone.classList.add('text-primary')
|
|
||||||
Clone.href = '#'
|
|
||||||
Clone.innerHTML = `
|
|
||||||
<i class="fa-duotone fa-book"></i>
|
|
||||||
Copy 3D Avatar URL
|
|
||||||
`
|
|
||||||
Clone.addEventListener('click', function(){
|
|
||||||
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 => {
|
|
||||||
data.assets.forEach(item => {
|
|
||||||
switch(item.type) {
|
|
||||||
case 'hat':
|
|
||||||
Avatar.items.push(item.path)
|
|
||||||
break
|
|
||||||
case 'tool':
|
|
||||||
Avatar.tool = item.path
|
|
||||||
break
|
|
||||||
case 'face':
|
|
||||||
Avatar.face = item.path
|
|
||||||
break
|
|
||||||
case 'shirt':
|
|
||||||
Avatar.shirt = item.path
|
|
||||||
break
|
|
||||||
case 'pants':
|
|
||||||
Avatar.pants = item.path
|
|
||||||
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'
|
|
||||||
|
|
||||||
const URL = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
|
|
||||||
console.log('URL: ', URL)
|
|
||||||
navigator.clipboard.writeText(URL)
|
|
||||||
const SwalCopied = document.createElement('script')
|
|
||||||
SwalCopied.innerHTML = `
|
|
||||||
window.Swal.fire({title: "Copied", icon: "success", html: "The 3D avatar URL has been copied to clipboard!<br><a href='${URL}' target='_blank'>Preview it here!</a>"})
|
|
||||||
`
|
|
||||||
document.body.prepend(SwalCopied)
|
|
||||||
SwalCopied.remove()
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Original.parentElement.appendChild(Clone)
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
function HandleIRLPrice() {
|
|
||||||
const NetWorthElement = document.getElementsByClassName('float-end text-success')[0];
|
|
||||||
const NetWorth = parseInt(NetWorthElement.innerText.replace(/,/g, ''));
|
|
||||||
let IRL;
|
|
||||||
let DISPLAY;
|
|
||||||
switch (Settings.IRLPriceWithCurrencyCurrency) {
|
|
||||||
case 0:
|
|
||||||
IRL = (NetWorth * 0.0099).toFixed(2)
|
|
||||||
DISPLAY = 'USD'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
IRL = (NetWorth * 0.009).toFixed(2)
|
|
||||||
DISPLAY = 'EUR'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
IRL = (NetWorth * 0.0131).toFixed(2)
|
|
||||||
DISPLAY = 'CAD'
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
IRL = (NetWorth * 0.0077).toFixed(2)
|
|
||||||
DISPLAY = 'GBP'
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
IRL = (NetWorth * 0.1691).toFixed(2)
|
|
||||||
DISPLAY = 'MXN'
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
IRL = (NetWorth * 0.0144).toFixed(2)
|
|
||||||
DISPLAY = 'AUD'
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
IRL = (NetWorth * 0.2338).toFixed(2)
|
|
||||||
DISPLAY = 'TRY'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
NetWorthElement.innerText = NetWorthElement.innerText + " ($" + IRL + " " + DISPLAY + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
function HandleBestFriends() {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result){
|
|
||||||
BestFriends = result.PolyPlus_BestFriends || [];
|
|
||||||
|
|
||||||
FavoriteBtn = document.createElement('button');
|
|
||||||
FavoriteBtn.classList = 'btn btn-warning btn-sm ml-2';
|
|
||||||
if (!(BestFriends.length === 7)) {
|
|
||||||
if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID))) {
|
|
||||||
FavoriteBtn.innerText = 'Remove Best Friend Status';
|
|
||||||
} else {
|
|
||||||
FavoriteBtn.innerText = 'Best Friend';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FavoriteBtn.innerText = 'Remove Best Friend Status (max 7/7)'
|
|
||||||
}
|
|
||||||
if (UserID !== JSON.parse(window.localStorage.getItem('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'
|
|
||||||
}
|
|
||||||
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 }
|
|
||||||
btn.setAttribute('disabled', 'true')
|
|
||||||
|
|
||||||
chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result) {
|
|
||||||
const BestFriends = result.PolyPlus_BestFriends || [];
|
|
||||||
const index = BestFriends.indexOf(parseInt(UserID));
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
// Number exists, remove it
|
|
||||||
BestFriends.splice(index, 1);
|
|
||||||
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"
|
|
||||||
console.log('Number', parseInt(UserID), 'added to BestFriends');
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_BestFriends': BestFriends, arrayOrder: true }, function() {
|
|
||||||
console.log('BestFriends saved successfully!');
|
|
||||||
setTimeout(function() {
|
|
||||||
btn.removeAttribute('disabled')
|
|
||||||
}, 1500)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener(function(changes, namespace) {
|
|
||||||
if ('PolyPlus_BestFriends' in changes) {
|
|
||||||
chrome.storage.sync.get(['PolyPlus_BestFriends'], function(result) {
|
|
||||||
BestFriends = result.PolyPlus_BestFriends || [];
|
|
||||||
|
|
||||||
if (!(BestFriends.length === 7)) {
|
|
||||||
if (Array.isArray(BestFriends) && BestFriends.includes(parseInt(UserID))) {
|
|
||||||
FavoriteBtn.innerText = 'Remove Best Friend Status'
|
|
||||||
} else {
|
|
||||||
FavoriteBtn.innerText = 'Best Friend'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FavoriteBtn.innerText = 'Remove Best Friend Status (max 7/7)'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function ClearBestFriends(){
|
|
||||||
chrome.storage.sync.set({ 'PolyPlus_BestFriends': {"BestFriends": []}, arrayOrder: true }, function() {
|
|
||||||
console.log('BestFriends saved successfully!');
|
|
||||||
setTimeout(function() {
|
|
||||||
btn.removeAttribute('disabled')
|
|
||||||
}, 1500)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function HandleOufitCost() {
|
|
||||||
const AvatarCost = {
|
|
||||||
Total: 0,
|
|
||||||
Limiteds: 0,
|
|
||||||
Exclusives: 0
|
|
||||||
}
|
|
||||||
for (let item of AvatarRow.children) {
|
|
||||||
const ItemID = item.getElementsByTagName('a')[0].href.split('/')[4]
|
|
||||||
await fetch('https://api.polytoria.com/v1/store/'+ItemID)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok')
|
|
||||||
}
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
let Price = data.price
|
|
||||||
if (data.isLimited === true) {
|
|
||||||
AvatarCost.Limiteds += 1
|
|
||||||
Price = data.averagePrice
|
|
||||||
} else if (data.sales === 0) {
|
|
||||||
AvatarCost.Exclusives += 1
|
|
||||||
Price = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
AvatarCost.Total += Price
|
|
||||||
})
|
|
||||||
.catch(error => {console.log(error)});
|
|
||||||
}
|
|
||||||
|
|
||||||
const TotalCostText = document.createElement('small')
|
|
||||||
TotalCostText.classList = 'text-muted'
|
|
||||||
TotalCostText.style.padding = '20px'
|
|
||||||
TotalCostText.innerHTML = `${ (AvatarCost.Limiteds > 0 || AvatarCost.Exclusives > 0) ? '~' : '' }<i class="pi pi-brick me-2"></i> ${AvatarCost.Total.toLocaleString()}${ (AvatarCost.Limiteds > 0) ? ` (has ${AvatarCost.Limiteds} limiteds)` : '' }${ (AvatarCost.Exclusives > 0) ? ` (has ${AvatarCost.Exclusives} exclusives)` : '' }`
|
|
||||||
AvatarRow.parentElement.parentElement.prepend(TotalCostText)
|
|
||||||
AvatarRow.parentElement.style.marginTop = '10px'
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
const Username = window.location.pathname.split('/')[2]
|
|
||||||
|
|
||||||
let Reference = new URLSearchParams(new URL(window.location.href).search).get('ref')
|
|
||||||
if (Reference === null) {
|
|
||||||
Reference = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch("https://api.polytoria.com/v1/users/find?username=" + Username)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
window.location.href = window.location.origin + decodeURIComponent(Reference)
|
|
||||||
} else {
|
|
||||||
return response.json()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
window.location.href = "https://polytoria.com/users/" + data.id
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log("An error occurred:", error);
|
|
||||||
});
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
<style>
|
|
||||||
#options {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
margin: 20px;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#options *:not(input) {
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#options *:not(input):not(:nth-child(2)) {
|
|
||||||
margin-bottom: 3.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 col-lg-3">
|
|
||||||
<div class="card mcard mb-3">
|
|
||||||
<h6 class="card-header">
|
|
||||||
<i class="fad fa-user-crown"></i>
|
|
||||||
Avatar
|
|
||||||
</h6>
|
|
||||||
<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;">
|
|
||||||
|
|
||||||
<label for="JSONUpload" style="display: block;">
|
|
||||||
<button aria-label="Upload JSON!" onclick="this.parentElement.previousElementSibling.click()">
|
|
||||||
<i class="fa-duotone fa-download"></i>
|
|
||||||
</button>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<button id="jsonSave" aria-label="Save as JSON!" style="display: block;">
|
|
||||||
<i class="fa-duotone fa-upload"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button id="openNewTab" aria-label="View in a new tab!" style="display: block;">
|
|
||||||
<i class="fa-duotone fa-up-right-from-square"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button aria-label="View in full screen!" style="display: block;" onclick="document.getElementById('viewFrame').requestFullscreen()">
|
|
||||||
<i class="fa-duotone fa-minimize"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<button id="myself" class="btn btn-outline-primary w-100 mb-3">
|
|
||||||
<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">
|
|
||||||
<i class="fa-duotone fa-trash"></i>
|
|
||||||
Clear
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card mcard">
|
|
||||||
<h6 class="card-header">
|
|
||||||
<i class="fad fa-palette"></i>
|
|
||||||
Body Colors
|
|
||||||
</h6>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="card-body text-center" id="body-parts">
|
|
||||||
<div style="margin-bottom: 5px">
|
|
||||||
<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>
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-lg-9">
|
|
||||||
<ul class="nav nav-pills nav-justified mb-3" id="tabs">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" data-tab="hat">
|
|
||||||
<i class="fas fa-hat-cowboy me-1"></i>
|
|
||||||
Hats
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-tab="tool">
|
|
||||||
<i class="fas fa-hammer me-1"></i>
|
|
||||||
Tools
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-tab="face">
|
|
||||||
<i class="fas fa-face-smile me-1"></i>
|
|
||||||
Faces
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-tab="shirt">
|
|
||||||
<i class="fas fa-tshirt me-1"></i>
|
|
||||||
Shirts
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" data-tab="pants">
|
|
||||||
<i class="fas fa-socks me-1"></i>
|
|
||||||
Pants
|
|
||||||
</a>
|
|
||||||
</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...">
|
|
||||||
<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>
|
|
||||||
<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;">
|
|
||||||
<div class="row alignleft itemgrid" id="wearing"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
{
|
|
||||||
"Date": "2023-7-17",
|
|
||||||
"Data": [
|
|
||||||
{
|
|
||||||
"USD": 0.009899999999999999,
|
|
||||||
"EUR": 0.011200000000000002,
|
|
||||||
"CAD": 0.0123,
|
|
||||||
"GBP": 0.008100000000000001,
|
|
||||||
"MXN": 0.1928,
|
|
||||||
"AUD": 0.014199999999999999,
|
|
||||||
"TRY": 0.1583
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"USD": 0.009072727272727274,
|
|
||||||
"EUR": 0.010163636363636363,
|
|
||||||
"CAD": 0.011290909090909091,
|
|
||||||
"GBP": 0.007363636363636363,
|
|
||||||
"MXN": 0.17534545454545455,
|
|
||||||
"AUD": 0.013418181818181819,
|
|
||||||
"TRY": 0.14616363636363636
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"USD": 0.00868695652173913,
|
|
||||||
"EUR": 0.009721739130434783,
|
|
||||||
"CAD": 0.010730434782608695,
|
|
||||||
"GBP": 0.007043478260869565,
|
|
||||||
"MXN": 0.1676521739130435,
|
|
||||||
"AUD": 0.012834782608695652,
|
|
||||||
"TRY": 0.13767826086956522
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"USD": 0.009087272727272727,
|
|
||||||
"EUR": 0.00996,
|
|
||||||
"CAD": 0.010625454545454546,
|
|
||||||
"GBP": 0.006981818181818182,
|
|
||||||
"MXN": 0.17294545454545454,
|
|
||||||
"AUD": 0.012698181818181819,
|
|
||||||
"TRY": 0.14424
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"USD": 0.008331666666666668,
|
|
||||||
"EUR": 0.009323333333333333,
|
|
||||||
"CAD": 0.00974,
|
|
||||||
"GBP": 0.006066666666666666,
|
|
||||||
"MXN": 0.15853333333333333,
|
|
||||||
"AUD": 0.012306666666666667,
|
|
||||||
"TRY": 0.13222
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"USD": 0.0079992,
|
|
||||||
"EUR": 0.008950399999999999,
|
|
||||||
"CAD": 0.0093504,
|
|
||||||
"GBP": 0.005824,
|
|
||||||
"MXN": 0.152192,
|
|
||||||
"AUD": 0.011814400000000001,
|
|
||||||
"TRY": 0.12693120000000002
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
export default {
|
|
||||||
DefaultSettings: {
|
|
||||||
PinnedGamesOn: false,
|
|
||||||
ForumMentsOn: false,
|
|
||||||
BestFriendsOn: false,
|
|
||||||
ImprovedFrListsOn: false,
|
|
||||||
IRLPriceWithCurrencyOn: true,
|
|
||||||
IRLPriceWithCurrencyCurrency: 0,
|
|
||||||
IRLPriceWithCurrencyPackage: 0,
|
|
||||||
HideNotifBadgesOn: true,
|
|
||||||
SimplifiedProfileURLsOn: true,
|
|
||||||
StoreOwnTagOn: true,
|
|
||||||
ThemeCreatorOn: false,
|
|
||||||
ThemeCreator: {
|
|
||||||
BGColor: null,
|
|
||||||
BGImage: null,
|
|
||||||
BGImageSize: 'fit',
|
|
||||||
PrimaryTextColor: null,
|
|
||||||
SecondaryTextColor: null,
|
|
||||||
LinkTextColor: null,
|
|
||||||
WebsiteLogo: null
|
|
||||||
},
|
|
||||||
ModifyNavOn: false,
|
|
||||||
ModifyNav: [
|
|
||||||
{
|
|
||||||
Label: "Play",
|
|
||||||
Link: "https://polytoria.com/places"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Store",
|
|
||||||
Link: "https://polytoria.com/store"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Guilds",
|
|
||||||
Link: "https://polytoria.com/guilds"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "People",
|
|
||||||
Link: "https://polytoria.com/users"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Forum",
|
|
||||||
Link: "https://polytoria.com/forum"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
MoreSearchFiltersOn: true,
|
|
||||||
ApplyMembershipThemeOn: false,
|
|
||||||
ApplyMembershipThemeTheme: 0,
|
|
||||||
ForumMarkOn: true,
|
|
||||||
MultiCancelOutTradesOn: true,
|
|
||||||
ItemWishlistOn: true,
|
|
||||||
HideUpgradeBtnOn: false
|
|
||||||
},
|
|
||||||
CalculateIRL: async function(bricks, to) {
|
|
||||||
const response = await fetch(chrome.runtime.getURL('/js/resources/currencies.json'))
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Getting currency data failure')
|
|
||||||
}
|
|
||||||
const data = await response.json()
|
|
||||||
|
|
||||||
let IRL;
|
|
||||||
let DISPLAY;
|
|
||||||
switch (to) {
|
|
||||||
case 0:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.0099).toFixed(2)
|
|
||||||
DISPLAY = 'USD'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.009).toFixed(2)
|
|
||||||
DISPLAY = 'EUR'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.0131).toFixed(2)
|
|
||||||
DISPLAY = 'CAD'
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.0077).toFixed(2)
|
|
||||||
DISPLAY = 'GBP'
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.1691).toFixed(2)
|
|
||||||
DISPLAY = 'MXN'
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.0144).toFixed(2)
|
|
||||||
DISPLAY = 'AUD'
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
IRL = (bricks.replace(/,/g, '') * 0.2338).toFixed(2)
|
|
||||||
DISPLAY = 'TRY'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return {bricks: IRL, display: DISPLAY}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
19
js/settings.js
Executable file
|
|
@ -0,0 +1,19 @@
|
||||||
|
const SettingsURL = chrome.runtime.getURL('settings.html');
|
||||||
|
const InExtensionSettings = window.location.pathname.split('/')[3] === 'polyplus' && window.location.hash !== '#dev' && window.location.hash !== '#debug';
|
||||||
|
|
||||||
|
if (InExtensionSettings === true) {
|
||||||
|
window.location.href = SettingsURL + window.location.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const Nav = document.getElementsByClassName('nav nav-pills')[0];
|
||||||
|
|
||||||
|
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]);
|
||||||
|
});
|
||||||
37
js/site-redirects.js
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
const URLs = [
|
||||||
|
{
|
||||||
|
Old: "/games/",
|
||||||
|
New: "/places/"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Old: "/shop/",
|
||||||
|
New: "/store/"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Old: "/my/referrals",
|
||||||
|
New: "/my/settings/referrals"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Old: "/create/?t=",
|
||||||
|
New: "/create/"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Old: "/user/",
|
||||||
|
New: "/users/"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Old: "/library/",
|
||||||
|
New: "/models/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
let Matches = URLs.filter((x) => window.location.pathname.startsWith(x.Old))
|
||||||
|
if (Matches.length > 0) {
|
||||||
|
let Match = Matches[0]
|
||||||
|
window.location.pathname = window.location.pathname.replace(Match.Old, Match.New)
|
||||||
|
}
|
||||||
289
js/sitewide.js
Executable file
|
|
@ -0,0 +1,289 @@
|
||||||
|
var Settings;
|
||||||
|
let Theme = ``;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default;
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
|
// Merge settings and expected settings to make sure all keys exist
|
||||||
|
const RawSettings = result.PolyPlus_Settings;
|
||||||
|
Settings = Utilities.MergeObjects(RawSettings || Utilities.DefaultSettings, Utilities.DefaultSettings);
|
||||||
|
|
||||||
|
const PageLoad = async function() {
|
||||||
|
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utilities.InjectResource('getUserDetails');
|
||||||
|
document.body.setAttribute('data-URL', window.location.pathname);
|
||||||
|
|
||||||
|
if (Settings.IRLPriceWithCurrency && 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) {
|
||||||
|
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) {
|
||||||
|
Needed[i].children[1].innerText = Settings.ModifyNav[i].Label;
|
||||||
|
Needed[i].href = Settings.ModifyNav[i].Link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.HideUserAds && Settings.HideUserAds.Enabled === true) {
|
||||||
|
if (Settings.HideUserAds.Banners && Settings.HideUserAds.Banners === true) {
|
||||||
|
Theme += `
|
||||||
|
div[style^="max-width: 728px;"]:has(a[href^="/ads"]) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.HideUserAds.Rectangles && Settings.HideUserAds.Rectangles === true) {
|
||||||
|
Theme += `
|
||||||
|
div[style^="max-width: 300px;"]:has(a[href^="/ads"]) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.HideNotifBadgesOn === true) {
|
||||||
|
document.getElementsByClassName('notifications-toggle')[0].getElementsByTagName('i')[0].classList = 'fa-bell far'
|
||||||
|
Theme += `
|
||||||
|
.notif-nav.notif-sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications-toggle {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notifications-toggle .unread-indicator {
|
||||||
|
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">`;
|
||||||
|
|
||||||
|
/*
|
||||||
|
chrome.storage.local.get(['PolyPlus_AdCache'], async function(result){
|
||||||
|
const AdCache = result.PolyPlus_AdCache || {};
|
||||||
|
|
||||||
|
const NewCacheAdditions = Array.from(document.querySelectorAll('a[href^="/ads"]')).map(async (ad) => {
|
||||||
|
const AdID = ad.getAttribute('href').split('/')[2]
|
||||||
|
if (Object.keys(AdCache).indexOf(AdID) === -1) {
|
||||||
|
const AssetURL = (await fetch(ad.href)).url
|
||||||
|
const AssetInfo = ((await fetch(AssetURL.replace('polytoria.com/', 'api.polytoria.com/v1/'))).json())
|
||||||
|
console.log(AssetInfo)
|
||||||
|
AdCache[AdID] = AssetInfo
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await Promise.all(NewCacheAdditions)
|
||||||
|
|
||||||
|
console.log(AdCache)
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (/\/inbox\/messages\/[0-9]+\/compose/.test(window.location.pathname) && new URLSearchParams(window.location.search).has('anniversaryPreset')) {
|
||||||
|
const AnniversaryNumber = parseInt(new URLSearchParams(window.location.search).get('anniversaryPreset'))
|
||||||
|
const MessageSubject = document.querySelector('[action^="/inbox"] #subject')
|
||||||
|
const MessageBody = document.querySelector('[action^="/inbox"] #body')
|
||||||
|
|
||||||
|
const RandomAnniversaryMessage = [
|
||||||
|
{
|
||||||
|
subject: "Happy :number+ Polytorian Anniversary!",
|
||||||
|
body: `Congratulations on your :number full year on Polytoria, :recipient! 🎉🎂🎈
|
||||||
|
|
||||||
|
Best wishes,
|
||||||
|
- :username
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: `:number Year${ (AnniversaryNumber > 1) ? 's' : '' } on Polytoria!`,
|
||||||
|
body: `Happy :number+ Polytorian Anniversary, :recipient! 🎈🎈🎉🎉
|
||||||
|
|
||||||
|
Yours truly,
|
||||||
|
- :username
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: `:number Year${ (AnniversaryNumber > 1) ? 's' : '' } of Polytorian Fun!`,
|
||||||
|
body: `I am so proud of you for reaching :number years on Polytoria, :recipient! 🎉🎂🎈
|
||||||
|
|
||||||
|
Warm regards,
|
||||||
|
- :username
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: "Congratulations on :number Years on Polytoria!",
|
||||||
|
body: `:recipient, you have been on Polytoria for :number ${ (AnniversaryNumber === 1) ? 'whole' : 'full' } years! I am writing to congratulate you on this amazing achievement! 🎉🎂🎈
|
||||||
|
|
||||||
|
With love and fun,
|
||||||
|
- :username
|
||||||
|
`
|
||||||
|
}
|
||||||
|
][Math.floor(Math.random() * 3) + 1]
|
||||||
|
|
||||||
|
MessageSubject.value = RandomAnniversaryMessage.subject.replace(':number', AnniversaryNumber).replace(':number+', AnniversaryNumber + (AnniversaryNumber % 10 === 1 && AnniversaryNumber % 100 !== 11 ? 'st' : AnniversaryNumber % 10 === 2 && AnniversaryNumber % 100 !== 12 ? 'nd' : AnniversaryNumber % 10 === 3 && AnniversaryNumber % 100 !== 13 ? 'rd' : 'th'))
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const NewMessageBody = document.createElement('textarea')
|
||||||
|
NewMessageBody.classList = 'form-control'
|
||||||
|
NewMessageBody.id = 'body'
|
||||||
|
NewMessageBody.name = 'body'
|
||||||
|
NewMessageBody.rows = '16'
|
||||||
|
NewMessageBody.innerHTML = RandomAnniversaryMessage.body.replace(':number', AnniversaryNumber).replace(':number+', AnniversaryNumber + (AnniversaryNumber % 10 === 1 && AnniversaryNumber % 100 !== 11 ? 'st' : AnniversaryNumber % 10 === 2 && AnniversaryNumber % 100 !== 12 ? 'nd' : AnniversaryNumber % 10 === 3 && AnniversaryNumber % 100 !== 13 ? 'rd' : 'th')).replace(':recipient', document.querySelector('[action^="/inbox"] a[href^="/u"]').innerText).replace(':username', document.querySelector('a[href^="/u"]:has(.dropdown-item):first-child').innerText.replaceAll('\n', '').replaceAll('\t', '').trim())
|
||||||
|
MessageBody.parentElement.appendChild(NewMessageBody)
|
||||||
|
MessageBody.remove()
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||||
|
PageLoad()
|
||||||
|
} else {
|
||||||
|
document.addEventListener('DOMContentLoaded', PageLoad);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply Theme
|
||||||
|
LoadTheme();
|
||||||
|
|
||||||
|
const combination = "reload";
|
||||||
|
let currentCombination = "";
|
||||||
|
document.addEventListener("keypress", function (e) {
|
||||||
|
currentCombination += e.key;
|
||||||
|
if (currentCombination === combination && document.activeElement.tagName !== "INPUT" && document.activeElement.tagName !== "TEXTAREA") {
|
||||||
|
try {
|
||||||
|
console.log("Reloading Poly+...");
|
||||||
|
chrome.runtime.sendMessage({ action: "reload" });
|
||||||
|
window.location.reload();
|
||||||
|
} catch(error) {
|
||||||
|
console.log("Reloading Poly+...");
|
||||||
|
window.location.reload()
|
||||||
|
chrome.runtime.sendMessage({ action: "reload" });
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
} else if (!combination.startsWith(currentCombination)) {
|
||||||
|
currentCombination = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
function LoadTheme() {
|
||||||
|
if (!Settings.ThemeCreator || Settings.ThemeCreator.Enabled !== true) { return }
|
||||||
|
|
||||||
|
switch (Settings.ThemeCreator.BGImageSize) {
|
||||||
|
case 0:
|
||||||
|
Settings.ThemeCreator.BGImageSize = 'fit';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Settings.ThemeCreator.BGImageSize = 'cover';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Settings.ThemeCreator.BGImageSize = 'contain';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Theme += `
|
||||||
|
:root {
|
||||||
|
--polyplus-navbgcolor: ${Settings.ThemeCreator.NavBGColor};
|
||||||
|
--polyplus-navbordercolor: ${Settings.ThemeCreator.NavBorderColor};
|
||||||
|
--polyplus-navitemcolor: ${Settings.ThemeCreator.NavItemColor};
|
||||||
|
--polyplus-sidebarbgcolor: ${Settings.ThemeCreator.SideBGColor};
|
||||||
|
--polyplus-sidebarbordercolor: ${Settings.ThemeCreator.SideBorderColor};
|
||||||
|
--polyplus-sidebaritembgcolor: ${Settings.ThemeCreator.SideItemBGColor};
|
||||||
|
--polyplus-sidebaritembordercolor: ${Settings.ThemeCreator.SideItemBorderColor};
|
||||||
|
--polyplus-sidebaritemcolor: ${Settings.ThemeCreator.SideItemColor};
|
||||||
|
--polyplus-sidebaritemlabelcolor: ${Settings.ThemeCreator.SideItemLabelColor};
|
||||||
|
--polyplus-bgcolor: ${Settings.ThemeCreator.BGColor};
|
||||||
|
--polyplus-bgimage: url(${Settings.ThemeCreator.BGImage});
|
||||||
|
--polyplus-bgimagesize: ${Settings.ThemeCreator.BGImageSize};
|
||||||
|
--polyplus-primarytextcolor: ${Settings.ThemeCreator.PrimaryTextColor};
|
||||||
|
--polyplus-secondarytextcolor: ${Settings.ThemeCreator.SecondaryTextColor};
|
||||||
|
--polyplus-linktextcolor: ${Settings.ThemeCreator.LinkTextColor};
|
||||||
|
--polyplus-linkhoveredtextcolor: ${Settings.ThemeCreator.LinkHoveredTextColor};
|
||||||
|
--polyplus-linkfocusedtextcolor: ${Settings.ThemeCreator.LinkFocusedTextColor};
|
||||||
|
--polyplus-linkvisitedtextcolor: ${Settings.ThemeCreator.LinkVisitedTextColor};
|
||||||
|
--polyplus-cardheadbgcolor: ${Settings.ThemeCreator.CardHeadBGColor};
|
||||||
|
--polyplus-cardbodybgcolor: ${Settings.ThemeCreator.CardBodyBGColor};
|
||||||
|
--polyplus-cardbordercolor: ${Settings.ThemeCreator.CardBorderColor};
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
background-color: var(--polyplus-navbgcolor) !important;
|
||||||
|
border-bottom: 1px solid var(--polyplus-navbordercolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-sidebar {
|
||||||
|
background-color: var(--polyplus-sidebarbgcolor) !important;
|
||||||
|
border-right: 1px solid var(--polyplus-sidebarbordercolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
background-color: var(--polyplus-bgcolor) !important;
|
||||||
|
background-image: var(--polyplus-bgimage) !important;
|
||||||
|
background-size var(--polyplus-bgimagesize)
|
||||||
|
color: var(--polyplus-primarytextcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: var(--polyplus-secondarytextcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--polyplus-linktextcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--polyplus-linkhoveredtextcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:focus {
|
||||||
|
color: var(--polyplus-linkfocusedtextcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
a:visited {
|
||||||
|
color: var(--polyplus-linkvisitedtextcolor) !important;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
background-color: var(--polyplus-cardheadbgcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: var(--polyplus-cardbodybgcolor) !important;
|
||||||
|
border-color: var(--polyplus-cardbordercolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a.nav-link {
|
||||||
|
color: var(--polyplus-navitemcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-sidebar .nav-sidebar-button {
|
||||||
|
background-color: var(--polyplus-sidebaritembgcolor) !important;
|
||||||
|
border-color: var(--polyplus-sidebaritembordercolor) !important;
|
||||||
|
color: var(--polyplus-sidebaritemcolor) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-sidebar-text {
|
||||||
|
color: var(--polyplus-sidebaritemlabelcolor) !important;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
@ -1,123 +1,369 @@
|
||||||
setTimeout(function () {}, 100)
|
const ItemID = window.location.pathname.split('/')[2];
|
||||||
var Settings = {IRLPriceWithCurrencyOn: true, IRLPriceWithCurrencyCurrency: 0, StoreOwnTagOn: true};
|
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID;
|
||||||
var UserID = JSON.parse(window.localStorage.getItem('account_info')).ID
|
const ItemGrid = document.getElementById('assets');
|
||||||
var ItemGrid = document.getElementById('assets')
|
const Categories = document.getElementById('store-categories').children[0];
|
||||||
var Inventory = [];
|
|
||||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
var Settings;
|
||||||
Settings = result.PolyPlus_Settings;
|
var Inventory = null;
|
||||||
|
var Utilities;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
|
Array.from(ItemGrid.children).forEach((element) => {
|
||||||
|
LoadIRLPrices(element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.EventItemsCatOn === true) {
|
||||||
|
EventItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.StoreOwnTagOn === true) {
|
||||||
|
chrome.storage.local.get('PolyPlus_InventoryCache', async function(result){
|
||||||
|
if (result.PolyPlus_InventoryCache !== undefined && (new Date().getTime() - result.PolyPlus_InventoryCache.requested < 30000)) {
|
||||||
|
Inventory = result.PolyPlus_InventoryCache.data
|
||||||
|
Array.from(ItemGrid.children).forEach((element) => {
|
||||||
|
LoadOwnedTags(element);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Inventory = (await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=hat&limit=100')).json());
|
||||||
|
if (Inventory.errors === undefined) {
|
||||||
|
Inventory = Inventory.inventory
|
||||||
|
Inventory = [...Inventory, ...(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=face&limit=100')).json()).inventory];
|
||||||
|
Inventory = [...Inventory, ...(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=tool&limit=100')).json()).inventory];
|
||||||
|
Inventory = [...Inventory, ...(await (await fetch('https://api.polytoria.com/v1/users/' + UserID + '/inventory?type=profileTheme&limit=100')).json()).inventory];
|
||||||
|
chrome.storage.local.set({'PolyPlus_InventoryCache': {data: Inventory, requested: new Date().getTime()}}, function(){})
|
||||||
|
Array.from(ItemGrid.children).forEach((element) => {
|
||||||
|
LoadOwnedTags(element);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(Inventory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function Update() {
|
const observer = new MutationObserver(async function (list) {
|
||||||
if (Settings.IRLPriceWithCurrencyOn === true) {
|
if (Settings.EventItemsCatOn === true) {
|
||||||
Array.from(ItemGrid.children).forEach(element => {LoadIRLPrices(element)});
|
if (document.getElementById('event-items-pagination') === null) {
|
||||||
}
|
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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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 (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||||
|
LoadIRLPrices(element);
|
||||||
|
}
|
||||||
|
|
||||||
const observer = new MutationObserver(async function (list){
|
if (Settings.StoreOwnTagOn === true && Inventory !== null) {
|
||||||
for (const record of list) {
|
LoadOwnedTags(element);
|
||||||
console.log('record')
|
}
|
||||||
for (const element of record.addedNodes) {
|
}
|
||||||
console.log('element', element.tagName, element.classList)
|
}
|
||||||
if (element.tagName === "DIV" && element.classList.value === 'mb-3 itemCardCont') {
|
observer.observe(ItemGrid, {attributes: false, childList: true, subtree: false});
|
||||||
if (Settings.IRLPriceWithCurrencyOn === true) {LoadIRLPrices(element)}
|
}
|
||||||
if (Settings.StoreOwnTagOn === true) {
|
|
||||||
if (Inventory.length === 0) {
|
|
||||||
await fetch("https://api.polytoria.com/v1/users/:id/inventory".replace(':id', UserID))
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network not ok')
|
|
||||||
}
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
Inventory = data.data;
|
|
||||||
LoadOwnedTags(element)
|
|
||||||
return
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
LoadOwnedTags(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observer.observe(ItemGrid, {attributes: false,childList: true,subtree: false});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
observer.observe(ItemGrid, {attributes: false,childList: true,subtree: false});
|
observer.observe(ItemGrid, {attributes: false, childList: true, subtree: false});
|
||||||
|
|
||||||
function LoadIRLPrices(element) {
|
async function LoadIRLPrices(element) {
|
||||||
if (element.tagName != "DIV") {return}
|
if (element.tagName != 'DIV' || element.querySelector('small.text-primary')) {
|
||||||
if (element.querySelector('small.text-primary')) {return}
|
return;
|
||||||
let Parent = element.getElementsByTagName('small')[1]
|
}
|
||||||
if (Parent.innerText === "") {
|
const Parent = element.getElementsByTagName('small')[1];
|
||||||
return
|
if (Parent.innerText !== '') {
|
||||||
}
|
const Span = document.createElement('span');
|
||||||
let Span = document.createElement('span')
|
Span.classList = 'text-muted polyplus-price-tag';
|
||||||
Span.classList = 'text-muted polyplus-price-tag'
|
Span.style = 'font-size: 0.7rem; font-weight: lighter;';
|
||||||
Span.style.fontSize = '0.7rem'
|
const Price = Parent.innerText.split(' ')[1];
|
||||||
let Price = parseInt(Parent.innerText.replace(/,/g, ''))
|
const IRLResult = await Utilities.CalculateIRL(Price, Settings.IRLPriceWithCurrency.Currency);
|
||||||
var IRL;
|
Span.innerText = '($' + IRLResult.result + ' ' + IRLResult.display + ')';
|
||||||
var DISPLAY;
|
Parent.appendChild(Span);
|
||||||
switch (Settings.IRLPriceWithCurrencyCurrency) {
|
}
|
||||||
case 0:
|
|
||||||
IRL = (Price * 0.0099).toFixed(2)
|
|
||||||
DISPLAY = 'USD'
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
IRL = (Price * 0.009).toFixed(2)
|
|
||||||
DISPLAY = 'EUR'
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
IRL = (Price * 0.0131).toFixed(2)
|
|
||||||
DISPLAY = 'CAD'
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
IRL = (Price * 0.0077).toFixed(2)
|
|
||||||
DISPLAY = 'GBP'
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
IRL = (Price * 0.1691).toFixed(2)
|
|
||||||
DISPLAY = 'MXN'
|
|
||||||
break
|
|
||||||
case 5:
|
|
||||||
IRL = (Price * 0.0144).toFixed(2)
|
|
||||||
DISPLAY = 'AUD'
|
|
||||||
break
|
|
||||||
case 6:
|
|
||||||
IRL = (Price * 0.2338).toFixed(2)
|
|
||||||
DISPLAY = 'TRY'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Span.innerText = "($" + IRL + " " + DISPLAY + ")"
|
|
||||||
Parent.appendChild(Span)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadOwnedTags(element) {
|
function LoadOwnedTags(element, id) {
|
||||||
let Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]))
|
let Item;
|
||||||
console.log(Item, Item.id)
|
if (id !== undefined) {
|
||||||
if (Item.id) {
|
Item = CheckInventory(parseInt(id))
|
||||||
var Tag = document.createElement('span')
|
} else {
|
||||||
Tag.classList = 'badge bg-primary polyplus-own-tag'
|
Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]));
|
||||||
Tag.setAttribute('style', 'position: absolute;font-size: 0.7rem;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;')
|
}
|
||||||
if (Item.asset.isLimited === false) {
|
if (Item !== null) {
|
||||||
Tag.innerText = "owned"
|
const Tag = document.createElement('span');
|
||||||
} else {
|
Tag.classList = `badge ${Item.asset.isLimited === false ? 'bg-primary' : 'bg-warning'} polyplus-own-tag`;
|
||||||
Tag.innerHTML = 'owned<br><span class="text-muted" style="font-size: 0.65rem;">#' + Item.serial
|
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;';
|
||||||
element.querySelector('img').parentElement.appendChild(Tag)
|
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);
|
||||||
|
|
||||||
|
Utilities.InjectResource('registerTooltips');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function CheckInventory(id) {
|
function CheckInventory(id) {
|
||||||
let Item = {}
|
let Item = null;
|
||||||
Inventory.forEach(element => {
|
Inventory.forEach((element) => {
|
||||||
if (element.asset.id === id) {
|
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';
|
||||||
|
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);
|
||||||
|
|
||||||
|
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');
|
||||||
|
if (EventData === null) {
|
||||||
|
EventData = await (await fetch('https://polyplus.vercel.app/data/eventItems.json')).json();
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemGrid.classList.remove('itemgrid');
|
||||||
|
ItemGrid.innerHTML = `
|
||||||
|
<div id="p+ei">
|
||||||
|
${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 ? typeof(x.link) !== "object" ? `
|
||||||
|
<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>
|
||||||
|
<i class="fas fa-angle-right ms-2"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
` : x.link.map(l => `
|
||||||
|
<div class="col-auto d-flex align-items-center">
|
||||||
|
<a class="text-muted" href="${l.link}">
|
||||||
|
<span class="d-none d-lg-inline">${l.label}</span>
|
||||||
|
<i class="fas fa-angle-right ms-2"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`).join('') : ''}
|
||||||
|
</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) => `
|
||||||
|
<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">
|
||||||
|
<img src="${x.thumbnail}" class="place-card-image">
|
||||||
|
<div>
|
||||||
|
<div class="mt-2 mb-1 place-card-title">
|
||||||
|
${x.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center mt-3">
|
||||||
|
<nav id="event-items-pagination">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link" href="#!" id="p+ei-pagination-first">«</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link" href="#!" id="p+ei-pagination-prev">‹</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item active">
|
||||||
|
<a class="page-link">
|
||||||
|
<span class="visually-hidden">Page</span>
|
||||||
|
<span id="p+ei-pagination-current">1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="#!" id="p+ei-pagination-next">›</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="#!" id="p+ei-pagination-last">»</a>
|
||||||
|
</li>
|
||||||
|
</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');
|
||||||
|
|
||||||
|
if (Settings.StoreOwnTagOn === true) {
|
||||||
|
Array.from(Container.querySelectorAll('a[href^="/store"]')).forEach((element) => {
|
||||||
|
LoadOwnedTags(element, element.getAttribute('href').split('/')[2]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Page > 0) {
|
||||||
|
Prev.parentElement.classList.remove('disabled');
|
||||||
|
First.parentElement.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
Prev.parentElement.classList.add('disabled');
|
||||||
|
First.parentElement.classList.add('disabled');
|
||||||
|
}
|
||||||
|
if (Page < Groups.length - 1) {
|
||||||
|
Next.parentElement.classList.remove('disabled');
|
||||||
|
Last.parentElement.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
Next.parentElement.classList.add('disabled');
|
||||||
|
Last.parentElement.classList.add('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
First.addEventListener('click', function () {
|
||||||
|
if (Page > 0) {
|
||||||
|
Page = 0;
|
||||||
|
UpdateEventItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Prev.addEventListener('click', function () {
|
||||||
|
if (Page > 0) {
|
||||||
|
Page--;
|
||||||
|
UpdateEventItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Next.addEventListener('click', function () {
|
||||||
|
if (Page < Groups.length - 1) {
|
||||||
|
Page++;
|
||||||
|
UpdateEventItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Last.addEventListener('click', function () {
|
||||||
|
if (Page < Groups.length - 1) {
|
||||||
|
Page = Groups.length - 1;
|
||||||
|
UpdateEventItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const UpdateEventItems = function () {
|
||||||
|
Current.innerText = Page + 1;
|
||||||
|
Container.innerHTML = Groups[Page].map((x, index) => `
|
||||||
|
<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 ? `
|
||||||
|
<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>
|
||||||
|
<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) => `
|
||||||
|
<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">
|
||||||
|
<img src="${x.thumbnail}" class="place-card-image">
|
||||||
|
<div>
|
||||||
|
<div class="mt-2 mb-1 place-card-title">
|
||||||
|
${x.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
).join('');
|
||||||
|
|
||||||
|
if (Page > 0) {
|
||||||
|
Prev.parentElement.classList.remove('disabled');
|
||||||
|
First.parentElement.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
Prev.parentElement.classList.add('disabled');
|
||||||
|
First.parentElement.classList.add('disabled');
|
||||||
|
}
|
||||||
|
if (Page < Groups.length - 1) {
|
||||||
|
Next.parentElement.classList.remove('disabled');
|
||||||
|
Last.parentElement.classList.remove('disabled');
|
||||||
|
} else {
|
||||||
|
Next.parentElement.classList.add('disabled');
|
||||||
|
Last.parentElement.classList.add('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.StoreOwnTagOn === true) {
|
||||||
|
Array.from(Container.querySelectorAll('a[href^="/store"]')).forEach((element) => {
|
||||||
|
LoadOwnedTags(element, element.getAttribute('href').split('/')[2]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
let 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"
|
|
||||||
}
|
|
||||||
|
|
||||||
const Style = document.createElement('style')
|
|
||||||
Style.innerHTML = `
|
|
||||||
html:has(.polyplus-modal[open]), body:has(.polyplus-modal[open]) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.polyplus-modal::backdrop {
|
|
||||||
background: rgba(0, 0, 0, 0.73);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
document.body.prepend(Style)
|
|
||||||
|
|
||||||
const ItemType = document.getElementsByClassName('px-4 px-lg-0 text-muted text-uppercase mb-3')[0].innerText.toLowerCase().split(' ')[1]
|
|
||||||
const ItemThumbnail = document.getElementsByClassName('store-thumbnail')[0]
|
|
||||||
const IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
|
|
||||||
const TryIFrame = document.createElement('iframe')
|
|
||||||
TryIFrame.setAttribute('style', 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px;')
|
|
||||||
|
|
||||||
const TryOnBtn = document.createElement('button')
|
|
||||||
TryOnBtn.classList = 'btn btn-outline-warning'
|
|
||||||
TryOnBtn.setAttribute('style', 'position: absolute; bottom: 15px;')
|
|
||||||
TryOnBtn.innerHTML = '<i class="fa-duotone fa-vial"></i>'
|
|
||||||
TryOnBtn.addEventListener('click', function (){
|
|
||||||
TryOnModal.showModal()
|
|
||||||
});
|
|
||||||
if (typeof(document.getElementsByClassName('3dviewtoggler')[0]) === 'object') {
|
|
||||||
TryOnBtn.style.right = '60px'
|
|
||||||
} else {
|
|
||||||
TryOnBtn.style.right = '10px'
|
|
||||||
}
|
|
||||||
|
|
||||||
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="text-muted mb-2" style="font-size: 0.8rem;">
|
|
||||||
<h5 class="mb-0" style="color: #fff;">Preview</h5>
|
|
||||||
Try on this item!
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<button class="btn btn-primary w-100 mx-auto" onclick="this.parentElement.parentElement.close();">Close</button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
|
|
||||||
document.body.prepend(TryOnModal)
|
|
||||||
ItemThumbnail.parentElement.appendChild(TryOnBtn)
|
|
||||||
TryOnModal.children[1].prepend(TryIFrame)
|
|
||||||
|
|
||||||
fetch("https://api.polytoria.com/v1/users/:id/avatar".replace(':id', JSON.parse(window.localStorage.getItem('account_info')).ID))
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network response was not ok');
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
data.assets.forEach(item => {
|
|
||||||
switch (item.type) {
|
|
||||||
case 'hat':
|
|
||||||
Avatar.items[Avatar.items.length] = item.path || ''
|
|
||||||
break
|
|
||||||
case 'face':
|
|
||||||
Avatar.face = item.path || ''
|
|
||||||
break
|
|
||||||
case 'tool':
|
|
||||||
Avatar.tool = item.path || ''
|
|
||||||
break
|
|
||||||
case 'shirt':
|
|
||||||
Avatar.shirt = item.path || ''
|
|
||||||
break
|
|
||||||
case 'pants':
|
|
||||||
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
|
|
||||||
|
|
||||||
if (ItemType === 'hat' || ItemType === 'tool') {
|
|
||||||
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 => {
|
|
||||||
if (ItemType === 'hat') {
|
|
||||||
Avatar.items[Avatar.items.length] = data.url
|
|
||||||
} else if (ItemType === 'tool') {
|
|
||||||
Avatar.tool = data.url
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(Avatar)
|
|
||||||
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Fetch error:', error);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
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 => {
|
|
||||||
switch (ItemType) {
|
|
||||||
case 'shirt':
|
|
||||||
Avatar.shirt = data.url
|
|
||||||
break
|
|
||||||
case 'pants':
|
|
||||||
Avatar.pants = data.url
|
|
||||||
break
|
|
||||||
case 'face':
|
|
||||||
Avatar.face = data.url
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)))
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Fetch error:', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Fetch error:', error);
|
|
||||||
});
|
|
||||||
96
js/the-great-divide.js
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
let EventOngoing = true;
|
||||||
|
let Team;
|
||||||
|
let HasTeam = true;
|
||||||
|
|
||||||
|
const PlaceAllowlist = [
|
||||||
|
'9656',
|
||||||
|
'9757'
|
||||||
|
];
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'))
|
||||||
|
.default
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
||||||
|
Settings = result.PolyPlus_Settings || {};
|
||||||
|
|
||||||
|
if (Settings.TheGreatDivide.Enabled !== true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.TheGreatDivide.UserStatsOn === true && window.location.pathname.split('/')[1] === 'u') {
|
||||||
|
if (HasTeam === true) {
|
||||||
|
UserStatsTab()
|
||||||
|
} else {
|
||||||
|
if (EventOngoing === true) {
|
||||||
|
UserStatsTab()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function UnbalancedServerMarkers() {
|
||||||
|
const Team = (await (await fetch('https://api.polytoria.com/v1/users/' + JSON.parse(window.localStorage.getItem('p+account_info')).ID + '/greatdivide')).json()).team
|
||||||
|
if (Team !== undefined) {
|
||||||
|
const Servers = Array.from(document.getElementById('servers-tabpane').children)
|
||||||
|
|
||||||
|
Servers.forEach(server => {
|
||||||
|
const TeamCounts = {
|
||||||
|
phantoms: server.getElementsByClassName('border-phantoms').length,
|
||||||
|
cobras: server.getElementsByClassName('border-cobras').length
|
||||||
|
}
|
||||||
|
|
||||||
|
let Enemy = "cobras"
|
||||||
|
if (Team === "cobras") { Enemy = "phantoms" }
|
||||||
|
|
||||||
|
if (new URLSearchParams(window.location.search).has('forceServerUnbalance')) {
|
||||||
|
TeamCounts[Enemy] = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TeamCounts[Team] < TeamCounts[Enemy]) {
|
||||||
|
const UnbalancedText = document.createElement('p')
|
||||||
|
UnbalancedText.classList = 'mb-2'
|
||||||
|
UnbalancedText.style.fontSize = '0.7rem'
|
||||||
|
UnbalancedText.style.color = 'orange'
|
||||||
|
UnbalancedText.innerHTML = `*Potentially Unbalanced <i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-title="${TeamCounts.cobras} Cobras and ${TeamCounts.phantoms} Phantoms" data-bs-placement="right"></i>`
|
||||||
|
|
||||||
|
const ServerInfoColumn = server.getElementsByClassName('col-3')[0]
|
||||||
|
ServerInfoColumn.children[0].style.marginBottom = '0px'
|
||||||
|
ServerInfoColumn.insertBefore(UnbalancedText, ServerInfoColumn.children[1])
|
||||||
|
|
||||||
|
Utilities.InjectResource("registerTooltips")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function UserStatsTab() {
|
||||||
|
const EventSection = document.createElement('div')
|
||||||
|
EventSection.innerHTML = `
|
||||||
|
<div class="d-grid mt-2 mb-4"></div>
|
||||||
|
<h6 class="text-center section-title px-3 px-lg-0 fw-bold" style="background-clip:text;-webkit-background-clip:text;color:transparent;background-image: linear-gradient(90deg, #1ad05b, #68f);-webkit-text-fill-color: transparent;">
|
||||||
|
<i class="fas fa-swords me-1 float-start"></i>
|
||||||
|
GREATEST DIVISION
|
||||||
|
<i class="fas fa-swords me-1 float-end"></i>
|
||||||
|
</h6>
|
||||||
|
<div class="card mcard mb-4" style="min-height: 226px; background-image: linear-gradient(rgba(0.7, 0.7, 0.7, 0.7), rgba(0.7, 0.7, 0.7, 0.7)), url('https://blog.polytoria.com/content/images/2024/06/TheGreatDivide.png'); background-size: cover; background-position: center; border-color: #000 !important;">
|
||||||
|
<div class="card-body" id="p+greatdivide_card">
|
||||||
|
<button class="btn btn-primary btn-sm w-100">Load Statistics</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
document.getElementsByClassName('user-right')[0].appendChild(EventSection)
|
||||||
|
|
||||||
|
const EventCard = document.getElementById('p+greatdivide_card')
|
||||||
|
EventCard.innerHTML = `
|
||||||
|
<small class="d-block text-center text-muted" style="font-size: 0.8rem;">
|
||||||
|
Loading...
|
||||||
|
</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>
|
||||||
|
`
|
||||||
|
await chrome.runtime.sendMessage({
|
||||||
|
action: "greatdivide_stats",
|
||||||
|
userID: document.querySelector('.dropdown-item.text-danger[href^="/report"]').getAttribute('href').split('?')[0].split('/')[3]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
279
manifest.json
Executable file → Normal file
|
|
@ -1,149 +1,174 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Poly+",
|
"author": "Index",
|
||||||
"version": "1.0",
|
"name": "Poly+",
|
||||||
"version_name": "Public Beta",
|
"version": "1.3",
|
||||||
"description": "Power-up your Polytoria experience with Poly+! Created by Index.",
|
"version_name": "Release Build (v1.3)",
|
||||||
"permissions": ["storage", "contextMenus", "tabs", "scripting", "alarms", "notifications"],
|
"description": "Power-up your Polytoria experience with Poly+! Created by Index.",
|
||||||
"content_scripts": [
|
"homepage_url": "https://polyplus.vercel.app/",
|
||||||
{
|
"permissions": ["storage", "contextMenus", "scripting", "alarms", "notifications"],
|
||||||
"matches": ["https://polytoria.com/*"],
|
"content_scripts": [
|
||||||
"js": ["/js/everywhere.js","/js/membership-themes.js"],
|
{
|
||||||
"css": ["/css/specific.css"],
|
"matches": ["https://polytoria.com/*"],
|
||||||
"run_at": "document_start"
|
"js": ["/js/sitewide.js", "/js/membership-themes.js"],
|
||||||
},
|
"css": ["/css/specific.css"],
|
||||||
|
"run_at": "document_start"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/settings/*"],
|
"matches": ["https://polytoria.com/my/settings/*"],
|
||||||
"js": ["/js/polyplus-settings.js"],
|
"js": ["/js/settings.js", "/js/extra-pages.js"],
|
||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/", "https://polytoria.com/home"],
|
"matches": ["https://polytoria.com/", "https://polytoria.com/home"],
|
||||||
"js": ["/js/account/home.js"],
|
"js": ["/js/account/home.js"],
|
||||||
"run_at": "document_idle"
|
"run_at": "document_idle"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/settings/polyplus-debug/*"],
|
"matches": ["https://polytoria.com/places/**"],
|
||||||
"js": ["/js/debug.js"]
|
"js": ["/js/places/place-view.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/places/**"],
|
"matches": ["https://polytoria.com/create/place/**/access"],
|
||||||
"js": ["/js/places/place-view2.js"]
|
"js": ["/js/create/place-access.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/join-place/**"],
|
"matches": ["https://polytoria.com/create/image", "https://polytoria.com/create/image/"],
|
||||||
"js": ["/js/places/place-join.js"]
|
"js": ["/js/create/image.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/create/place/**"],
|
"matches": ["https://polytoria.com/forum/post/**"],
|
||||||
"js": ["/js/places/place-edit.js"]
|
"js": ["/js/forum/forum-view.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/forum/post/**"],
|
"matches": ["https://polytoria.com/u/**", "https://polytoria.com/users/**"],
|
||||||
"js": ["/js/forum/forum-view.js"]
|
"js": ["/js/account/profile.js", "/js/account/inventory.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/users/**"],
|
"matches": ["https://polytoria.com/my/friends", "https://polytoria.com/my/friends/"],
|
||||||
"js": ["/js/profile/profile.js"]
|
"js": ["/js/account/friends.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/profile/**"],
|
"matches": ["https://polytoria.com/store", "https://polytoria.com/store/"],
|
||||||
"js": ["/js/profile/simplified-profile.js"],
|
"js": ["/js/store/store.js"]
|
||||||
"run_at": "document_start"
|
},
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/friends", "https://polytoria.com/my/friends/"],
|
"matches": ["https://polytoria.com/store/**", "https://polytoria.com/store/*/asset"],
|
||||||
"js": ["/js/account/friends.js"]
|
"js": ["/js/store/item-view.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/store", "https://polytoria.com/store/"],
|
"matches": ["https://polytoria.com/forum/search", "https://polytoria.com/forum/search?*"],
|
||||||
"js": ["/js/store/store.js"]
|
"js": ["/js/forum/forum-search.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/store/**"],
|
"matches": ["https://polytoria.com/trade/sent/*"],
|
||||||
"js": ["/js/store/item-view.js"]
|
"js": ["/js/account/trades-outbound.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/forum/search","https://polytoria.com/forum/search?*"],
|
"matches": ["https://polytoria.com/u/*/inventory/"],
|
||||||
"js": ["/js/forum/forum-search.js"]
|
"js": ["/js/account/inventory.js"],
|
||||||
},
|
"run_at": "document_idle"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/trade/sent/*"],
|
"matches": ["https://polytoria.com/my/settings/privacy"],
|
||||||
"js": ["/js/account/trades-outbound.js"]
|
"js": ["/js/account/settings-privacy.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/users/*/inventory/*"],
|
"matches": ["https://polytoria.com/my/settings/transactions*"],
|
||||||
"js": ["/js/account/inventory.js"],
|
"js": ["/js/account/transactions.js"]
|
||||||
"run_at": "document_idle"
|
},
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/settings/privacy"],
|
"matches": ["https://polytoria.com/store/**", "https://polytoria.com/places/**", "https://polytoria.com/guilds/**", "https://polytoria.com/feed/**"],
|
||||||
"js": ["/js/account/settings-privacy.js"]
|
"js": ["/js/op-comments.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/settings/transactions"],
|
"matches": ["https://polytoria.com/my/avatar*"],
|
||||||
"js": ["/js/account/transactions.js"]
|
"js": ["/js/account/avatar-sandbox.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/store/**", "https://polytoria.com/places/**", "https://polytoria.com/guilds/**", "https://polytoria.com/feed/**"],
|
"matches": ["https://polytoria.com/inbox*"],
|
||||||
"js": ["/js/op-comments.js"]
|
"js": ["/js/account/inbox.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/my/avatar?sandbox=true"],
|
"matches": ["https://polytoria.com/guilds/**"],
|
||||||
"js": ["/js/account/avatar-sandbox2.js"]
|
"js": ["/js/guilds.js"]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"matches": ["https://polytoria.com/inbox/*", "https://polytoria.com/inbox?*"],
|
"matches": ["https://polytoria.com/store/**", "https://polytoria.com/models/**"],
|
||||||
"js": ["/js/account/inbox.js"]
|
"js": ["/js/library-download.js"]
|
||||||
}
|
},
|
||||||
],
|
|
||||||
"background": {
|
{
|
||||||
"service_worker": "/js/background.js",
|
"matches": ["https://polytoria.com/games/*", "https://polytoria.com/shop/*", "https://polytoria.com/my/referrals", "https://polytoria.com/create/?t=*", "https://polytoria.com/user/*", "https://polytoria.com/library/*"],
|
||||||
"type": "module"
|
"js": ["/js/site-redirects.js"]
|
||||||
},
|
},
|
||||||
"host_permissions": [
|
|
||||||
"https://*.polytoria.com/*"
|
{
|
||||||
],
|
"matches": ["https://polytoria.com/library"],
|
||||||
"web_accessible_resources": [
|
"js": ["/js/create/audio-library.js"]
|
||||||
{
|
},
|
||||||
"resources": ["js/resources/*"],
|
|
||||||
"matches": ["https://polytoria.com/*"]
|
{
|
||||||
}
|
"matches": ["https://polytoria.com/u/**"],
|
||||||
],
|
"js": ["/js/the-great-divide.js"]
|
||||||
"short_name": "Poly+",
|
},
|
||||||
"action": {
|
|
||||||
"default_title": "Poly+",
|
{
|
||||||
"default_icon": {
|
"matches": ["https://polytoria.com/trade/view/**"],
|
||||||
"16": "/icon.png",
|
"js": ["/js/account/trade-valuation.js"]
|
||||||
"32": "/icon.png",
|
}
|
||||||
"48": "/icon.png",
|
],
|
||||||
"128": "/icon.png"
|
"background": {
|
||||||
}
|
"service_worker": "/js/background.js",
|
||||||
},
|
"type": "module"
|
||||||
"icons": {
|
},
|
||||||
"16": "/icon.png",
|
"host_permissions": ["https://*.polytoria.com/*"],
|
||||||
"32": "/icon.png",
|
"web_accessible_resources": [
|
||||||
"48": "/icon.png",
|
{
|
||||||
"128": "/icon.png"
|
"resources": ["resources/*"],
|
||||||
}
|
"matches": ["https://polytoria.com/*"]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"resources": ["settings.html", "settings.js"],
|
||||||
|
"matches": ["https://polytoria.com/*"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"short_name": "Poly+",
|
||||||
|
"action": {
|
||||||
|
"default_title": "Poly+",
|
||||||
|
"default_icon": {
|
||||||
|
"16": "/images/icon.png",
|
||||||
|
"32": "/images/icon.png",
|
||||||
|
"48": "/images/icon.png",
|
||||||
|
"128": "/images/icon.png"
|
||||||
|
},
|
||||||
|
"default_popup": "/popup.html"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"16": "/images/icon.png",
|
||||||
|
"32": "/images/icon.png",
|
||||||
|
"48": "/images/icon.png",
|
||||||
|
"128": "/images/icon.png"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
97
old.js
|
|
@ -1,97 +0,0 @@
|
||||||
let CurrencyNames = [
|
|
||||||
"USD",
|
|
||||||
"EUR",
|
|
||||||
"CAD",
|
|
||||||
"GBP",
|
|
||||||
"MXN",
|
|
||||||
"AUD",
|
|
||||||
"TRY"
|
|
||||||
]
|
|
||||||
|
|
||||||
let Divides = [
|
|
||||||
100,
|
|
||||||
550,
|
|
||||||
1150,
|
|
||||||
2750,
|
|
||||||
6000,
|
|
||||||
12500
|
|
||||||
]
|
|
||||||
|
|
||||||
let Currencies = [
|
|
||||||
[
|
|
||||||
0.99, // USD
|
|
||||||
1.12, // EUR
|
|
||||||
1.23, // CAD
|
|
||||||
0.81, // GBP
|
|
||||||
19.28, // MXN
|
|
||||||
1.42, // AUD
|
|
||||||
15.83, // TRY
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
4.99, // USD
|
|
||||||
5.59, // EUR
|
|
||||||
6.21, // CAD
|
|
||||||
4.05, // GBP
|
|
||||||
96.44, // MXN
|
|
||||||
7.38, // AUD
|
|
||||||
80.39, // TRY
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
9.99, // USD
|
|
||||||
11.18, // EUR
|
|
||||||
12.34, // CAD
|
|
||||||
8.10, // GBP
|
|
||||||
192.80, // MXN
|
|
||||||
14.76, // AUD
|
|
||||||
158.33, // TRY
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
24.99, // USD
|
|
||||||
27.39, // EUR
|
|
||||||
29.22, // CAD
|
|
||||||
19.20, // GBP
|
|
||||||
475.60, // MXN
|
|
||||||
34.92, // AUD
|
|
||||||
396.66, // TRY
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
49.99, // USD
|
|
||||||
55.94, // EUR
|
|
||||||
58.44, // CAD
|
|
||||||
36.40, // GBP
|
|
||||||
951.20, // MXN
|
|
||||||
73.84, // AUD
|
|
||||||
793.32, // TRY
|
|
||||||
],
|
|
||||||
|
|
||||||
[
|
|
||||||
99.99, // USD
|
|
||||||
111.88, // EUR
|
|
||||||
116.88, // CAD
|
|
||||||
72.80, // GBP
|
|
||||||
1902.40, // MXN
|
|
||||||
147.68, // AUD
|
|
||||||
1586.64, // TRY
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
let UnitPrices = [
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
|
|
||||||
Currencies.forEach((_value, _index) => {
|
|
||||||
Currencies[_index].forEach((value, index) => {
|
|
||||||
UnitPrices[_index][CurrencyNames[index]] = (value / Divides[_index])
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(JSON.stringify(UnitPrices))
|
|
||||||
37
popup.html
Executable file → Normal file
|
|
@ -1,11 +1,36 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html style="border-radius: 20px;">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Poly+</title>
|
<!-- META TAGS -->
|
||||||
</head>
|
<meta charset="utf-8" />
|
||||||
<body>
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<div style="text-align: center; width: 300px; padding: 10px;">
|
|
||||||
<a class="btn" href="https://polytoria.com/my/settings/polyplus">Settings</a>
|
<!-- PUBLIC -->
|
||||||
|
<title>Poly+ Settings</title>
|
||||||
|
|
||||||
|
<!-- RESOURCES -->
|
||||||
|
<link rel="stylesheet" href="css/polytoria.css" />
|
||||||
|
</head>
|
||||||
|
<body style="width: 245px;">
|
||||||
|
<div class="p-2 pt-0">
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">quick links</small>
|
||||||
|
<br>
|
||||||
|
<a href="#" class="btn btn-primary btn-sm w-100 mb-1" id="settings-btn" target="_window">Settings</a>
|
||||||
|
<a href="https://polytoria.com/my/settings/polyplus#debug" class="btn btn-warning btn-sm w-100 mb-1" target="_window">Debug</a>
|
||||||
|
<div class="d-flex" style="gap: 5px;">
|
||||||
|
<a href="https://chromewebstore.google.com/detail/poly+/feafepokhecfmimpepbpccmcnjbcbklg" class="btn btn-dark btn-sm w-100" target="_window"><img src="/images/chrome-icon.svg" alt="Chrome Webstore" width="25" height="25"></a>
|
||||||
|
<a href="https://addons.mozilla.org/en-US/firefox/addon/polytoriaplus/" class="btn btn-dark btn-sm w-100" target="_window"><img src="/images/firefox-icon.svg" alt="Chrome Webstore" width="25" height="25"></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="mt-2 mb-3" style="color: #2b2b2b;">
|
||||||
|
|
||||||
|
<small class="text-muted" style="font-size: 0.7rem;">extract texture from item</small>
|
||||||
|
<br>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control form-control-sm" placeholder="Item ID..">
|
||||||
|
<button class="btn btn-success btn-sm" id="extract-texture">Extract</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="popup.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
89
popup.js
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
ParseGLB & GetTexture function code made by ChatGPT (I didn't want to use external libraries because of storage space)
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.getElementById('settings-btn').href = chrome.runtime.getURL('settings.html')
|
||||||
|
|
||||||
|
const ExtractButton = document.getElementById('extract-texture')
|
||||||
|
|
||||||
|
ExtractButton.addEventListener('click', async function(){
|
||||||
|
const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + ExtractButton.previousElementSibling.value)).json()).url
|
||||||
|
|
||||||
|
if (MeshURL !== undefined) {
|
||||||
|
const Mesh = (await (await fetch(MeshURL)).arrayBuffer())
|
||||||
|
const ParsedGTLF = ParseGLB(Mesh)
|
||||||
|
|
||||||
|
const Texture = GetTexture(ParsedGTLF);
|
||||||
|
if (Texture) {
|
||||||
|
const DownloadLink = document.createElement('a');
|
||||||
|
|
||||||
|
DownloadLink.href = Texture;
|
||||||
|
DownloadLink.download = ExtractButton.previousElementSibling.value + '.png';
|
||||||
|
document.body.appendChild(DownloadLink)
|
||||||
|
DownloadLink.click()
|
||||||
|
DownloadLink.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function ParseGLB(arrayBuffer) {
|
||||||
|
const MAGIC_glTF = 0x46546C67;
|
||||||
|
|
||||||
|
const dataView = new DataView(arrayBuffer);
|
||||||
|
|
||||||
|
const magic = dataView.getUint32(0, true);
|
||||||
|
if (magic !== MAGIC_glTF) {
|
||||||
|
throw new Error('Invalid GLB file.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = dataView.getUint32(4, true);
|
||||||
|
if (version !== 2) {
|
||||||
|
throw new Error('Unsupported GLB version.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const length = dataView.getUint32(8, true);
|
||||||
|
const chunkLength = dataView.getUint32(12, true);
|
||||||
|
const chunkType = dataView.getUint32(16, true);
|
||||||
|
|
||||||
|
if (chunkType !== 0x4E4F534A) {
|
||||||
|
throw new Error('Invalid GLB JSON chunk.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonChunk = new TextDecoder().decode(
|
||||||
|
new Uint8Array(arrayBuffer, 20, chunkLength)
|
||||||
|
);
|
||||||
|
const json = JSON.parse(jsonChunk);
|
||||||
|
|
||||||
|
const binChunkHeader = 20 + chunkLength;
|
||||||
|
const binChunkLength = dataView.getUint32(binChunkHeader, true);
|
||||||
|
const binChunkType = dataView.getUint32(binChunkHeader + 4, true);
|
||||||
|
|
||||||
|
if (binChunkType !== 0x004E4942) {
|
||||||
|
throw new Error('Invalid GLB BIN chunk.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const binChunk = arrayBuffer.slice(binChunkHeader + 8, binChunkHeader + 8 + binChunkLength);
|
||||||
|
|
||||||
|
return {
|
||||||
|
json: json,
|
||||||
|
bin: binChunk
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetTexture(gltf) {
|
||||||
|
let Texture = null
|
||||||
|
|
||||||
|
const images = gltf.json.images;
|
||||||
|
if (images.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const image = images[0];
|
||||||
|
const bufferView = gltf.json.bufferViews[image.bufferView];
|
||||||
|
const byteOffset = bufferView.byteOffset || 0;
|
||||||
|
const byteLength = bufferView.byteLength;
|
||||||
|
const buffer = new Uint8Array(gltf.bin, byteOffset, byteLength);
|
||||||
|
|
||||||
|
const blob = new Blob([buffer], { type: image.mimeType });
|
||||||
|
return URL.createObjectURL(blob);
|
||||||
|
}
|
||||||
383
resources/avatar-sandbox.html
Executable file
|
|
@ -0,0 +1,383 @@
|
||||||
|
<style>
|
||||||
|
#options {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
background: #1a1a1a;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 2.5px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
button iteration #2
|
||||||
|
|
||||||
|
font-size: 1.25rem;
|
||||||
|
background: #333333;
|
||||||
|
border-radius: var(--bs-card-border-radius);
|
||||||
|
padding: 2.5px;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
left: -1px;
|
||||||
|
bottom: -1px;
|
||||||
|
border-top-left-radius: 0px;
|
||||||
|
border-bottom-right-radius: 0px;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#options *:not(input) {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#options *:not(input):not(:nth-child(2)) {
|
||||||
|
margin-bottom: 3.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class^="p+outfit_overwrite_button"]:hover, [class^="p+outfit_delete_button"]:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[id="p+retro_items_warning"] {
|
||||||
|
display: none;
|
||||||
|
color: #000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
body:has([data-tab="retro"].active) [id="p+retro_items_warning"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<dialog id="p+body_colors" class="polyplus-modal" style="width: 375px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;">
|
||||||
|
<div class="row text-muted mb-4" style="font-size: 0.8rem;">
|
||||||
|
<div class="col">
|
||||||
|
<h5 class="mb-0" style="color: #fff;">Modify Body Colors</h5>
|
||||||
|
Selected Body Part: <i id="p+selected_bodypart">none</i>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button class="btn btn-info w-100 mx-auto" onclick="this.parentElement.parentElement.parentElement.close();">X</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="colorpicker-color" style="background-color: #f8f8f8"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #cdcdcd"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #111111"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ff0000"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #a34b4b"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffc9c9"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #957977"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #c4281c"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #da867a"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #694028"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #cc8e69"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #a05f35"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #7c5c46"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #eab892"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #da8541"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #aa5500"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffcc99"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #e29b40"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffaf00"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffb000"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #d7c59a"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #f5cd30"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #fdea8d"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #e5e4df"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #c1be42"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffff00"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ffffcc"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #a4bd47"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #7f8e64"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #a1c48c"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #3a7d15"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #4b974b"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #00ff00"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ccffcc"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #27462d"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #287f47"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #789082"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #9ff3e9"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #12eed4"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #f2f3f3"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #00ffff"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #008f9c"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #04afec"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #80bbdb"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #b4d2e4"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #0d69ac"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #1b2a35"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #afddff"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #6e99ca"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #74869d"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #2154b9"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #002060"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #0000ff"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #b1a7ff"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #a3a2a5"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #6225d1"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #b480ff"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #8c5b9f"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #6b327c"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #aa00aa"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #635f62"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ff00bf"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #ff66cc"></div>
|
||||||
|
<div class="colorpicker-color" style="background-color: #e8bac8"></div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group mt-2">
|
||||||
|
<input type="text" class="form-control bg-dark" placeholder="HEX Code..">
|
||||||
|
<button id="p+bodypart_customhex" class="btn btn-primary">Set</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="p+outfit_create" class="polyplus-modal" style="width: 375px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;">
|
||||||
|
<div class="row text-muted mb-4" style="font-size: 0.8rem;">
|
||||||
|
<div class="col">
|
||||||
|
<h5 class="mb-0" style="color: #fff;">Create Outfit</h5>
|
||||||
|
Save this avatar for later!
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<button class="btn btn-info w-100 mx-auto" onclick="this.parentElement.parentElement.parentElement.close();">X</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="input-group mb-2">
|
||||||
|
<input type="text" class="form-control" placeholder="Outfit Name...">
|
||||||
|
<button id="p+save_outfit_confirm" class="btn btn-success">Save</button>
|
||||||
|
</div>
|
||||||
|
<b id="p+outfit_create_error" class="text-muted" style="font-size: 0.85rem;"><i class="fa-duotone fa-square-question mr-1"></i> ...</b>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="p+outfit_rename" class="polyplus-modal" style="width: 375px; border: 1px solid #484848; background-color: #181818; border-radius: 20px; overflow: hidden;">
|
||||||
|
<div class="row text-muted mb-4" style="font-size: 0.8rem;">
|
||||||
|
<div class="col">
|
||||||
|
<h5 class="mb-0" style="color: #fff;">Rename Outfit</h5>
|
||||||
|
Renaming Outfit "<i id="p+outfit_rename_name">none</i>"
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<button class="btn btn-info w-100 mx-auto" onclick="this.parentElement.parentElement.parentElement.close();">X</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="input-group mb-2">
|
||||||
|
<input type="text" class="form-control" placeholder="New Outfit Name...">
|
||||||
|
<button id="p+rename_outfit_confirm" class="btn btn-success">Save</button>
|
||||||
|
</div>
|
||||||
|
<b id="p+outfit_rename_error" class="text-muted" style="font-size: 0.85rem;"><i class="fa-duotone fa-square-question mr-1"></i> ...</b>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
<span class="badge bg-warning mb-2" id="view-cache">Poly+</span>
|
||||||
|
<h4 class="d-none d-lg-block">
|
||||||
|
Avatar Sandbox
|
||||||
|
</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-lg-3">
|
||||||
|
<div class="card mcard mb-3">
|
||||||
|
<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;" />
|
||||||
|
|
||||||
|
<label for="JSONUpload" style="display: block;">
|
||||||
|
<button aria-label="Upload JSON!" onclick="this.parentElement.previousElementSibling.click()" data-bs-toggle="tooltip" data-bs-title="Upload" data-bs-placement="right">
|
||||||
|
<i class="fa-duotone fa-upload"></i>
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button id="jsonSave" aria-label="Save as JSON!" style="display: block;" data-bs-toggle="tooltip" data-bs-title="Download" data-bs-placement="right">
|
||||||
|
<i class="fa-duotone fa-download"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button aria-label="View in full screen!" style="display: block;" onclick="document.getElementById('viewFrame').requestFullscreen()" data-bs-toggle="tooltip" data-bs-title="Full Screen" data-bs-placement="right">
|
||||||
|
<i class="fa-duotone fa-minimize"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="myself" class="btn btn-outline-primary w-100 mb-2">
|
||||||
|
<i class="fa-duotone fa-shirt"></i>
|
||||||
|
Load Myself
|
||||||
|
</button>
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<button id="clear" class="btn btn-outline-warning w-100">
|
||||||
|
<i class="fa-duotone fa-trash"></i>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button id="saveOutfit" class="btn btn-outline-success w-100">
|
||||||
|
<i class="fa-duotone fa-save"></i>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mt-2 mb-3">
|
||||||
|
<div class="card mcard mb-3">
|
||||||
|
<h6 class="card-header text-center">
|
||||||
|
<i class="fad fa-wrench"></i>
|
||||||
|
Advanced
|
||||||
|
</h6>
|
||||||
|
<div class="card-body">
|
||||||
|
<small class="text-muted mb-1" style="font-size: 0.7rem;">Wear asset by ID</small>
|
||||||
|
<br>
|
||||||
|
<select class="form-select bg-dark mb-1" id="load-asset-type">
|
||||||
|
<option value="hat" selected>Hat</option>
|
||||||
|
<option value="tool">Tool</option>
|
||||||
|
<option value="face">Face</option>
|
||||||
|
<option value="torso">Body Part</option>
|
||||||
|
<hr>
|
||||||
|
<option value="shirt">Shirt</option>
|
||||||
|
<option value="pants">Pants</option>
|
||||||
|
<hr>
|
||||||
|
<option value="user">User Avatar</option>
|
||||||
|
</select>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control bg-dark" placeholder="Asset ID.." />
|
||||||
|
<button class="btn btn-primary" id="load-asset">Wear</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mcard mb-1">
|
||||||
|
<h6 class="card-header text-center">
|
||||||
|
<i class="fad fa-palette"></i>
|
||||||
|
Body Colors
|
||||||
|
</h6>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-body text-center" id="body-parts">
|
||||||
|
<div style="margin-bottom: 5px">
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted text-center" style="font-size: 0.7rem;">thanks to <a href="https://polytoria.com/u/Hawli">@Hawli</a> and <a href="https://polytoria.com/u/Emir">@Emir</a> for letting me use their<br><a href="https://poly-archive.vercel.app/" target="_blank">Poly-Archive</a> website's assets!</small>
|
||||||
|
<hr class="mt-2 mb-1">
|
||||||
|
<small class="text-muted text-center" style="font-size: 0.7rem;">feature of Poly+</small>
|
||||||
|
<!--
|
||||||
|
Public API does not have an offsale parameter
|
||||||
|
|
||||||
|
<span class="form-check form-switch" style="font-size: 0.7rem;">
|
||||||
|
<input class="form-check-input" type="checkbox" role="switch" id="show-offsale" checked />
|
||||||
|
<label class="form-check-label" for="hide-user-ads-banner">Show Offsale Items</label>
|
||||||
|
</span>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-lg-9">
|
||||||
|
<ul class="nav nav-pills no-shrink avatar-nav-pills nav-justified row" id="tabs">
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link active" data-tab="hat">
|
||||||
|
<i class="fas fa-hat-wizard me-1"></i>
|
||||||
|
<span class="pilltitle">Accessories</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="shirt">
|
||||||
|
<i class="fas fa-tshirt me-1"></i>
|
||||||
|
<span class="pilltitle">Shirts</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="pants">
|
||||||
|
<i class="fas fa-socks me-1"></i>
|
||||||
|
<span class="pilltitle">Pants</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="tool">
|
||||||
|
<i class="fas fa-hammer me-1"></i>
|
||||||
|
<span class="pilltitle">Tools</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="face">
|
||||||
|
<i class="fas fa-face-smile me-1"></i>
|
||||||
|
<span class="pilltitle">Faces</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="torso">
|
||||||
|
<i class="fas fa-cube me-1"></i>
|
||||||
|
<span class="pilltitle">Body Parts</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="retro" data-bs-toggle="tooltip" data-bs-title="Items from Bloxtopia, Superium, and Polytoria v1!">
|
||||||
|
<i class="fa-solid fa-tv-retro me-1"></i>
|
||||||
|
<span class="pilltitle">Retro</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item col-6 col-md-4 col-xl-3" style="flex: unset">
|
||||||
|
<a class="nav-link" data-tab="outfit">
|
||||||
|
<i class="fas fa-person me-1"></i>
|
||||||
|
<span class="pilltitle">Outfits</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div role="alert" class="alert bg-warning text-center mb-1 mt-2" id="p+retro_items_warning">
|
||||||
|
Items in this category are from past iterations of Polytoria. They can only be worn in the Avatar Sandbox.
|
||||||
|
</div>
|
||||||
|
<div class="card px-2 pt-2 pb-2 mb-2" style="background: transparent; border-color: transparent; border-top-left-radius: 20px; border-top-right-radius: 20px;">
|
||||||
|
<div class="row mb-1">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="input-group">
|
||||||
|
<select id="item-sort" class="form-select retro-items-disable">
|
||||||
|
<option value="name">Name</option>
|
||||||
|
<option value="price">Price</option>
|
||||||
|
<option value="createdAt" selected>Creation Date</option>
|
||||||
|
<option value="updatedAt">Updated Date</option>
|
||||||
|
</select>
|
||||||
|
<select id="item-order" class="form-select retro-items-disable">
|
||||||
|
<option value="asc">Ascending</option>
|
||||||
|
<option value="desc">Descending</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="input-group">
|
||||||
|
<input id="item-search" type="text" class="form-control mb-2 retro-items-disable" placeholder="Search for an item..." />
|
||||||
|
<button id="search-btn" class="btn btn-primary h-100 retro-items-disable">Search</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row alignleft itemgrid mb-4" id="inventory"></div>
|
||||||
|
<nav id="pagination" style="margin: auto;">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item disabled" id="pagination-first">
|
||||||
|
<a class="page-link" href="#!">«</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled" id="pagination-prev">
|
||||||
|
<a class="page-link" href="#!">‹</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item active">
|
||||||
|
<a class="page-link">
|
||||||
|
<span class="visually-hidden">Page</span>
|
||||||
|
<span id="pagination-current">1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item" id="pagination-next">
|
||||||
|
<a class="page-link" href="#!">›</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item" id="pagination-last">
|
||||||
|
<a class="page-link" href="#!">»</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<h6 class="card-header mb-2"><i class="fad fa-hat-wizard me-1"></i> Wearing</h6>
|
||||||
|
<div class="card px-2 pt-2 pb-2 mb-4" style="background: transparent; border-color: transparent; border-top-left-radius: 20px; border-top-right-radius: 20px;">
|
||||||
|
<div class="row alignleft itemgrid" id="wearing"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
8
resources/getUserDetails.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
window.localStorage.setItem(
|
||||||
|
'p+account_info',
|
||||||
|
JSON.stringify({
|
||||||
|
ID: userID,
|
||||||
|
Username: document.querySelector('a[href^="/u"]:has(.dropdown-item):first-child').innerText.replaceAll('\n', '').replaceAll('\t', '').trim(),
|
||||||
|
Bricks: document.querySelector('.brickBalanceCont').innerText.replace(/\s+/g, '').split('(')[0]
|
||||||
|
})
|
||||||
|
);
|
||||||
5
resources/registerTooltips.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
var tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||||
|
var tooltip_list = [...tooltips].map((tool) => new bootstrap.Tooltip(tool));
|
||||||
|
|
||||||
|
var dropdowns = document.querySelectorAll('[data-bs-toggle="dropdown"]');
|
||||||
|
var dropdown_list = [...dropdowns].map((dropdown) => new bootstrap.Dropdown(dropdown));
|
||||||
317
resources/utils.js
Normal file
|
|
@ -0,0 +1,317 @@
|
||||||
|
/*
|
||||||
|
HOW TO USE IN CONTENT SCRIPTS:
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
|
Utilities = Utilities.default
|
||||||
|
})();
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ParseFullNumber(ab) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
DefaultSettings: {
|
||||||
|
PinnedGamesOn: true,
|
||||||
|
ForumMentsOn: true,
|
||||||
|
BestFriendsOn: false,
|
||||||
|
ImprovedFrListsOn: false,
|
||||||
|
IRLPriceWithCurrency: {
|
||||||
|
Enabled: true,
|
||||||
|
Currency: 0,
|
||||||
|
Package: 0
|
||||||
|
},
|
||||||
|
IRLPriceWithCurrencyOn: true,
|
||||||
|
IRLPriceWithCurrencyCurrency: 0,
|
||||||
|
IRLPriceWithCurrencyPackage: 0,
|
||||||
|
HideNotifBadgesOn: false,
|
||||||
|
StoreOwnTagOn: true,
|
||||||
|
ThemeCreatorOn: false,
|
||||||
|
ThemeCreator: {
|
||||||
|
Enabled: false,
|
||||||
|
BGColor: null,
|
||||||
|
BGImage: null,
|
||||||
|
BGImageSize: 'fit',
|
||||||
|
PrimaryTextColor: null,
|
||||||
|
SecondaryTextColor: null,
|
||||||
|
LinkTextColor: null,
|
||||||
|
WebsiteLogo: null
|
||||||
|
},
|
||||||
|
ModifyNavOn: false,
|
||||||
|
ModifyNav: [
|
||||||
|
{
|
||||||
|
Label: 'Places',
|
||||||
|
Link: 'https://polytoria.com/places'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Store',
|
||||||
|
Link: 'https://polytoria.com/store'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Guilds',
|
||||||
|
Link: 'https://polytoria.com/guilds'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'People',
|
||||||
|
Link: 'https://polytoria.com/users'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: 'Forum',
|
||||||
|
Link: 'https://polytoria.com/forum'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
MoreSearchFiltersOn: true,
|
||||||
|
ApplyMembershipTheme: {
|
||||||
|
Enabled: false,
|
||||||
|
Theme: 0
|
||||||
|
},
|
||||||
|
ApplyMembershipThemeOn: false,
|
||||||
|
ApplyMembershipThemeTheme: 0,
|
||||||
|
MultiCancelOutTradesOn: true,
|
||||||
|
ItemWishlistOn: true,
|
||||||
|
HideUpgradeBtnOn: false,
|
||||||
|
TryOnItemsOn: true,
|
||||||
|
OutfitCostOn: true,
|
||||||
|
ShowPlaceRevenueOn: true,
|
||||||
|
ReplaceItemSalesOn: false,
|
||||||
|
HoardersListOn: true,
|
||||||
|
HoardersList: {
|
||||||
|
Enabled: true,
|
||||||
|
AvatarsEnabled: false,
|
||||||
|
MinCopies: 2
|
||||||
|
},
|
||||||
|
LibraryDownloadsOn: true,
|
||||||
|
EventItemsCatOn: true,
|
||||||
|
HomeFriendCountOn: true,
|
||||||
|
HideUserAds: {
|
||||||
|
Enabled: false,
|
||||||
|
Banners: true,
|
||||||
|
Rectangles: true
|
||||||
|
},
|
||||||
|
UploadMultipleDecals: true,
|
||||||
|
GD_ServerBalanceOn: true,
|
||||||
|
AvatarDimensionToggleOn: true,
|
||||||
|
TheGreatDivide: {
|
||||||
|
Enabled: true,
|
||||||
|
UnbalancedIndicatorOn: true,
|
||||||
|
MVPUserIndicatorOn: true,
|
||||||
|
UserStatsOn: true,
|
||||||
|
LeaderboardsOn: true
|
||||||
|
},
|
||||||
|
CollectibleInventoryCatOn: true,
|
||||||
|
ValueListInfo: {
|
||||||
|
Enabled: true,
|
||||||
|
ItemValuation: true,
|
||||||
|
TradeValuation: true
|
||||||
|
},
|
||||||
|
ImprovedAchievements: {
|
||||||
|
Enabled: true,
|
||||||
|
ProgressBarOn: true,
|
||||||
|
PercentageOn: true,
|
||||||
|
OpacityOn: true
|
||||||
|
},
|
||||||
|
TimePlayedOn: true,
|
||||||
|
HomeJoinFriendsButtonOn: true,
|
||||||
|
ImprovedPlaceManagement: {
|
||||||
|
Enabled: true,
|
||||||
|
QuickActivityToggleOn: true,
|
||||||
|
PlaceFileDownloadOn: true,
|
||||||
|
MultiWhitelistOn: true,
|
||||||
|
ClearWhitelistOn: true
|
||||||
|
},
|
||||||
|
MoreBlockedDetailsOn: true,
|
||||||
|
AssetDesignerCreditOn: true
|
||||||
|
},
|
||||||
|
Limits: {
|
||||||
|
PinnedGames: 10,
|
||||||
|
BestFriends: 15,
|
||||||
|
// Item Wishlist and ImprovedFrLists limit here is not implemented in the code
|
||||||
|
ImprovedFrLists: 20,
|
||||||
|
ItemWishlist: 20,
|
||||||
|
HoardersListPages: 4
|
||||||
|
},
|
||||||
|
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
|
||||||
|
|
||||||
|
const response = await fetch(chrome.runtime.getURL('resources/currencies.json'))
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Getting currency data failure')
|
||||||
|
}
|
||||||
|
const data = await response.json()
|
||||||
|
const UnitPrice = data.Data[brickPackage][to]
|
||||||
|
*/
|
||||||
|
|
||||||
|
let Icon = '$';
|
||||||
|
let Result = 'N/A';
|
||||||
|
let Display = 'Currency Not Found';
|
||||||
|
|
||||||
|
// is the icon abbreviated text, or an entity
|
||||||
|
let IsIconAbbr = false;
|
||||||
|
|
||||||
|
bricks = ParseFullNumber(bricks.replace(/,/g, ''));
|
||||||
|
switch (to) {
|
||||||
|
// U.S. Dollar
|
||||||
|
case 0:
|
||||||
|
Result = (bricks * 0.0099).toFixed(2);
|
||||||
|
Display = 'USD';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Euro
|
||||||
|
case 1:
|
||||||
|
Icon = '€';
|
||||||
|
Result = (bricks * 0.009).toFixed(2);
|
||||||
|
Display = 'EUR';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Canadian Dollar
|
||||||
|
case 2:
|
||||||
|
Icon = 'CAD$';
|
||||||
|
IsIconAbbr = true;
|
||||||
|
|
||||||
|
Result = (bricks * 0.0131).toFixed(2);
|
||||||
|
Display = 'CAD';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Great British Pound
|
||||||
|
case 3:
|
||||||
|
Icon = '£';
|
||||||
|
Result = (bricks * 0.0077).toFixed(2);
|
||||||
|
Display = 'GBP';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Mexican Peso
|
||||||
|
case 4:
|
||||||
|
Icon = 'MXN$';
|
||||||
|
IsIconAbbr = true;
|
||||||
|
|
||||||
|
Result = (bricks * 0.1691).toFixed(2);
|
||||||
|
Display = 'MXN';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Australia Dollar
|
||||||
|
case 5:
|
||||||
|
Icon = 'AU$';
|
||||||
|
IsIconAbbr = true;
|
||||||
|
|
||||||
|
Result = (bricks * 0.0144).toFixed(2);
|
||||||
|
Display = 'AUD';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Turkish Lira
|
||||||
|
case 6:
|
||||||
|
Icon = '₺';
|
||||||
|
Result = (bricks * 0.2338).toFixed(2);
|
||||||
|
Display = 'TRY';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Brazillian Real
|
||||||
|
case 7:
|
||||||
|
Icon = 'R$';
|
||||||
|
IsIconAbbr = true;
|
||||||
|
|
||||||
|
Result = (bricks * 0.49).toFixed(2);
|
||||||
|
Display = 'BRL';
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Zimbabwean Dollar
|
||||||
|
case 8:
|
||||||
|
Icon = 'Z$'
|
||||||
|
IsIconAbbr = true
|
||||||
|
|
||||||
|
Result = (bricks * 0.13739106).toFixed(2)
|
||||||
|
Display = 'ZWL'
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof Result === 'number') {
|
||||||
|
Result = Result.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsIconAbbr) {
|
||||||
|
Icon = "$"
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
result: Result,
|
||||||
|
display: Display,
|
||||||
|
icon: Icon,
|
||||||
|
isIconAbbr: IsIconAbbr
|
||||||
|
};
|
||||||
|
},
|
||||||
|
InjectResource: function (path, element) {
|
||||||
|
/*
|
||||||
|
Function by devjin0617 on GitHub
|
||||||
|
Gist: https://gist.github.com/devjin0617/3e8d72d94c1b9e69690717a219644c7a
|
||||||
|
Slightly modified to use constants and fit the rest of the code style more
|
||||||
|
Function only used for registering bootstrap tooltips and getting the signed-in user's username, user ID, and brick count currently
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Potentially make this use chrome.runtime.sendMessage in the background.js script soon
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
Node.appendChild(Script);
|
||||||
|
},
|
||||||
|
// MergeObjects function was written by ChatGPT cause I was lazy and it was a while ago
|
||||||
|
MergeObjects: function(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;
|
||||||
|
},
|
||||||
|
RatelimitRepeatingFetch: async function (...args) {
|
||||||
|
const req = await fetch(...args);
|
||||||
|
|
||||||
|
if (req.status === 429) {
|
||||||
|
const retryAfter = req.headers.get('Retry-After') || 1; // Retry after 1 second if no header is present, else use the header value
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
|
||||||
|
return RatelimitRepeatingFetch(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
};
|
||||||
1433
settings.html
784
settings.js
Executable file → Normal file
|
|
@ -1,377 +1,469 @@
|
||||||
const SaveBtn = document.getElementById('Save')
|
const SaveBtn = document.getElementById('Save');
|
||||||
const Elements = Array.from(document.getElementsByClassName('setting-container'))
|
const Elements = Array.from(document.getElementsByClassName('setting-container'));
|
||||||
|
|
||||||
|
var RecentSave;
|
||||||
var Settings;
|
var Settings;
|
||||||
var ExpectedSettings = {
|
|
||||||
PinnedGamesOn: true,
|
|
||||||
ForumMentsOn: false,
|
|
||||||
BestFriendsOn: true,
|
|
||||||
ImprovedFrListsOn: true,
|
|
||||||
IRLPriceWithCurrencyOn: true,
|
|
||||||
IRLPriceWithCurrencyCurrency: 0,
|
|
||||||
IRLPriceWithCurrencyPackage: 0,
|
|
||||||
HideNotifBadgesOn: false,
|
|
||||||
StoreOwnTagOn: true,
|
|
||||||
ThemeCreatorOn: false,
|
|
||||||
ThemeCreator: {
|
|
||||||
BGColor: null,
|
|
||||||
BGImage: null,
|
|
||||||
BGImageSize: 'fit',
|
|
||||||
PrimaryTextColor: null,
|
|
||||||
SecondaryTextColor: null,
|
|
||||||
LinkTextColor: null,
|
|
||||||
WebsiteLogo: null
|
|
||||||
},
|
|
||||||
ModifyNavOn: false,
|
|
||||||
ModifyNav: [
|
|
||||||
{
|
|
||||||
Label: "Places",
|
|
||||||
Link: "https://polytoria.com/places"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Store",
|
|
||||||
Link: "https://polytoria.com/store"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Guilds",
|
|
||||||
Link: "https://polytoria.com/guilds"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "People",
|
|
||||||
Link: "https://polytoria.com/users"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Label: "Forum",
|
|
||||||
Link: "https://polytoria.com/forum"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
MoreSearchFiltersOn: true,
|
|
||||||
ApplyMembershipThemeOn: false,
|
|
||||||
ApplyMembershipThemeTheme: 0,
|
|
||||||
MultiCancelOutTradesOn: true,
|
|
||||||
ItemWishlistOn: true,
|
|
||||||
HideUpgradeBtnOn: false
|
|
||||||
}
|
|
||||||
|
|
||||||
const ResetDefaultsModal = document.getElementById('ResetDefaults-Modal')
|
var Utilities;
|
||||||
var ThemeCreatorModal = {
|
(async () => {
|
||||||
Modal: document.getElementById('ThemeCreator-Modal'),
|
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||||
Save: document.getElementById('ThemeCreator-Modal-Save'),
|
Utilities = Utilities.default;
|
||||||
BGColor: document.getElementById('ThemeCreator-Modal-BGColor'),
|
LoadCurrent();
|
||||||
BGImage: document.getElementById('ThemeCreator-Modal-BGImage'),
|
|
||||||
BGImageSize: document.getElementById('ThemeCreator-Modal-BGImageSize'),
|
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames;
|
||||||
PrimaryTextColor: document.getElementById('ThemeCreator-Modal-PrimaryTextColor'),
|
//document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists;
|
||||||
SecondaryTextColor: document.getElementById('ThemeCreator-Modal-SecondaryTextColor'),
|
//document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist;
|
||||||
LinkTextColor: document.getElementById('ThemeCreator-Modal-LinkTextColor'),
|
document.getElementById('HoardersList-pageLimit').innerText = Utilities.Limits.HoardersListPages;
|
||||||
WebsiteLogo: document.getElementById('ThemeCreator-Modal-WebsiteLogo')
|
})();
|
||||||
}
|
|
||||||
var ModifyNavModal = {
|
// Handle buttons at the bottom of the page
|
||||||
Modal: document.getElementById('ModifyNav-Modal'),
|
document.getElementById('ResetDefaults').addEventListener('click', function () {
|
||||||
Save: document.getElementById('ModifyNav-Modal-Save'),
|
document.getElementById('ResetDefaults-Modal').showModal();
|
||||||
"1Label": document.getElementById('ModifyNav-Modal-1Label'),
|
|
||||||
"1Link": document.getElementById('ModifyNav-Modal-1Link'),
|
|
||||||
"2Label": document.getElementById('ModifyNav-Modal-2Label'),
|
|
||||||
"2Link": document.getElementById('ModifyNav-Modal-2Link'),
|
|
||||||
"3Label": document.getElementById('ModifyNav-Modal-3Label'),
|
|
||||||
"3Link": document.getElementById('ModifyNav-Modal-3Link'),
|
|
||||||
"4Label": document.getElementById('ModifyNav-Modal-4Label'),
|
|
||||||
"4Link": document.getElementById('ModifyNav-Modal-4Link'),
|
|
||||||
"5Label": document.getElementById('ModifyNav-Modal-5Label'),
|
|
||||||
"5Link": document.getElementById('ModifyNav-Modal-5Link'),
|
|
||||||
}
|
|
||||||
SaveBtn.addEventListener("click", function() {
|
|
||||||
Save();
|
|
||||||
});
|
});
|
||||||
Elements.forEach(element => {
|
SaveBtn.addEventListener('click', Save);
|
||||||
let Button = element.getElementsByTagName('button')[0]
|
|
||||||
let Options = element.getElementsByTagName('button')[1]
|
|
||||||
let Select = element.getElementsByTagName('select') || []
|
|
||||||
|
|
||||||
if (Button) {
|
// Handle modal buttons for Reset Defaults modal
|
||||||
Button.addEventListener('click', function() {
|
document.getElementById('ResetDefaults-Modal-Yes').addEventListener('click', function () {
|
||||||
ToggleSetting(Button.getAttribute('data-setting'), element)
|
Settings = Utilities.DefaultSettings;
|
||||||
});
|
Save();
|
||||||
}
|
setTimeout(function () {
|
||||||
|
LoadCurrent();
|
||||||
if (Options) {
|
document.getElementById('ResetDefaults-Modal').close();
|
||||||
Options.addEventListener('click', function() {
|
}, 400);
|
||||||
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 => {
|
|
||||||
if (!(btn.getAttribute('data-ignore') === 'true')) {
|
|
||||||
btn.addEventListener('click', function(){
|
|
||||||
let Setting = btn.getAttribute('data-setting')
|
|
||||||
if (Setting === '[save]') {
|
|
||||||
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
|
|
||||||
} 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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
|
|
||||||
} 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Save();
|
|
||||||
setTimeout(function () {
|
|
||||||
LoadCurrent();
|
|
||||||
Modal.close();
|
|
||||||
}, 400)
|
|
||||||
} else if (Setting === '[cancel]') {
|
|
||||||
Modal.close();
|
|
||||||
} else if (Setting === '[callback]') {
|
|
||||||
let Function = btn.getAttribute('data-onclick')
|
|
||||||
if (window[Function] && typeof(window[Function]) === 'function') {
|
|
||||||
console.log('is')
|
|
||||||
window[Function]()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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')]
|
|
||||||
} else {
|
|
||||||
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')]
|
|
||||||
} else {
|
|
||||||
input.value = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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')]
|
|
||||||
}
|
|
||||||
} 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')]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Modal.showModal()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Select.length > 0) {
|
|
||||||
Array.from(Select).forEach(element => {
|
|
||||||
element.addEventListener('change', function() {
|
|
||||||
SetSetting(element.getAttribute('data-setting'), element, element.selectedIndex)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
document.getElementById('ResetDefaults').addEventListener('click', function() {
|
document.getElementById('ResetDefaults-Modal-No').addEventListener('click', function () {
|
||||||
ResetDefaultsModal.showModal();
|
document.getElementById('ResetDefaults-Modal').close();
|
||||||
});
|
});
|
||||||
document.getElementById('ResetDefaults-Modal-Yes').addEventListener('click', function() {
|
|
||||||
Settings = ExpectedSettings
|
// Loop thru each setting container and handle toggling, selecting, opening modal, etc
|
||||||
Save()
|
Elements.forEach((element) => {
|
||||||
setTimeout(function () {
|
let Button = element.getElementsByClassName('toggle-btn')[0];
|
||||||
LoadCurrent();
|
let Options = element.getElementsByClassName('options-btn')[0];
|
||||||
ResetDefaultsModal.close();
|
let Select = element.getElementsByTagName('select')[0];
|
||||||
}, 400)
|
let Checkbox = element.getElementsByTagName('input');
|
||||||
});
|
|
||||||
document.getElementById('ResetDefaults-Modal-No').addEventListener('click', function() {
|
if (Button) {
|
||||||
ResetDefaultsModal.close();
|
Button.addEventListener('click', function () {
|
||||||
|
SetSetting(Button, 'bool');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Select) {
|
||||||
|
Select.addEventListener('change', function () {
|
||||||
|
if (Select.getAttribute('data-useValue') !== null) {
|
||||||
|
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) {
|
||||||
|
Array.from(Checkbox).forEach(check => {
|
||||||
|
check.addEventListener('change', function () {
|
||||||
|
SetSetting(check, check.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
|
||||||
|
|
||||||
|
// Save Modal Inputs
|
||||||
|
Array.from(ModalInputs)
|
||||||
|
.filter((x) => !x.classList.contains('ignore'))
|
||||||
|
.forEach((input) => {
|
||||||
|
SetSetting(input, input.value, false, Modal.getAttribute('data-setting'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save Modal Select Menus
|
||||||
|
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() {
|
function LoadCurrent() {
|
||||||
chrome.storage.sync.get(["PolyPlus_Settings"], function(result) {
|
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||||
Settings = MergeObjects(result.PolyPlus_Settings || ExpectedSettings, ExpectedSettings)
|
Settings = Utilities.MergeObjects(result.PolyPlus_Settings || Utilities.DefaultSettings, Utilities.DefaultSettings);
|
||||||
|
RecentSave = structuredClone(Settings)
|
||||||
|
|
||||||
console.log(Settings)
|
console.log('Current Settings: ', Settings);
|
||||||
|
|
||||||
Elements.forEach(element => {
|
Elements.forEach((element) => {
|
||||||
let Status = element.getElementsByClassName('status')[0]
|
UpdateElementState(element);
|
||||||
console.log(element, FormatBool(Settings[element.getElementsByTagName('button')[0].getAttribute('data-setting')]))
|
});
|
||||||
Status.innerText = FormatBool(Settings[element.getElementsByTagName('button')[0].getAttribute('data-setting')])
|
});
|
||||||
let SelectInput = element.getElementsByTagName('select')[0]
|
|
||||||
if (SelectInput) {
|
|
||||||
SelectInput.selectedIndex = Settings[SelectInput.getAttribute('data-setting')]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
LoadCurrent();
|
|
||||||
|
|
||||||
function ToggleSetting(Name, Element) {
|
|
||||||
if (Settings[Name] === true) {
|
|
||||||
Settings[Name] = false;
|
|
||||||
} else {
|
|
||||||
Settings[Name] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Element != null) {
|
|
||||||
Element.getElementsByClassName('status')[0].innerText = FormatBool(Settings[Name])
|
|
||||||
}
|
|
||||||
if (SaveBtn.getAttribute('disabled')) {
|
|
||||||
SaveBtn.removeAttribute('disabled')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetSetting(Name, Element, Value) {
|
function SetSetting(element, value, update, modalParent) {
|
||||||
console.log(Settings)
|
document.title = '*unsaved | Poly+ Settings'
|
||||||
Settings[Name] = Value
|
const name = element.getAttribute('data-setting');
|
||||||
|
let parent = element.getAttribute('data-parent');
|
||||||
|
|
||||||
if (SaveBtn.getAttribute('disabled')) {
|
if (modalParent !== undefined) {
|
||||||
SaveBtn.removeAttribute('disabled')
|
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) {
|
||||||
|
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');
|
||||||
|
|
||||||
|
// Handle leaving the settings page before saving
|
||||||
|
window.onbeforeunload = function (e) {
|
||||||
|
return "Are you sure you'd like to leave? Your Poly+ settings haven't been saved."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (AreIdentical(Settings, RecentSave) === true) {
|
||||||
|
document.title = 'Poly+ Settings'
|
||||||
|
SaveBtn.disabled = true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
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)];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Status = Settings[Status];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.tagName === 'SELECT' && element.getAttribute('data-useValue') === 'true') {
|
||||||
|
Status = Array.from(element.children).indexOf(element.querySelector('option[value="' + Status + '"]'))
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateElementState(element, status) {
|
||||||
|
const Button = element.getElementsByClassName('toggle-btn')[0];
|
||||||
|
|
||||||
|
if (status === undefined) {
|
||||||
|
status = GetSettingValue(Button);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === true) {
|
||||||
|
element.classList.add('enabled');
|
||||||
|
element.classList.remove('disabled');
|
||||||
|
Button.innerText = 'Disable';
|
||||||
|
Button.classList.add('btn-danger');
|
||||||
|
Button.classList.remove('btn-success');
|
||||||
|
} else {
|
||||||
|
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) {
|
||||||
|
SelectInput.selectedIndex = GetSettingValue(SelectInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
let Checkbox = Array.from(element.getElementsByTagName('input'));
|
||||||
|
if (Checkbox.length > 0) {
|
||||||
|
Checkbox.forEach((check) => {
|
||||||
|
check.checked = GetSettingValue(check);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Save() {
|
function Save() {
|
||||||
SaveBtn.setAttribute('disabled', 'true')
|
document.title = 'Poly+ Settings';
|
||||||
chrome.storage.sync.set({ 'PolyPlus_Settings': Settings, arrayOrder: true }, function() {
|
SaveBtn.setAttribute('disabled', 'true');
|
||||||
console.log('Saved successfully!');
|
chrome.storage.sync.set({PolyPlus_Settings: Settings}, function () {
|
||||||
});
|
console.log('Saved successfully!');
|
||||||
|
RecentSave = Settings
|
||||||
|
});
|
||||||
|
|
||||||
console.log(Settings);
|
// Handle leaving the settings page after saving
|
||||||
|
window.onbeforeunload = null
|
||||||
|
|
||||||
|
console.log('Save:', Settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn')
|
let LoadThemeFromJSONBtn = document.getElementById('LoadThemeFromJSONBtn');
|
||||||
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput')
|
let SaveThemeToJSONInput = document.getElementById('SaveThemeToJSONInput');
|
||||||
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn')
|
let CopyThemeJSONBtn = document.getElementById('CopyThemeJSONBtn');
|
||||||
LoadThemeFromJSONBtn.addEventListener('click', function(){
|
LoadThemeFromJSONBtn.addEventListener('click', function () {
|
||||||
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value)
|
LoadThemeJSON(LoadThemeFromJSONBtn.previousElementSibling.value);
|
||||||
});
|
});
|
||||||
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].addEventListener('click', function(){
|
document
|
||||||
SaveThemeToJSONInput.value = JSON.stringify(Settings.ThemeCreator)
|
.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.');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
CopyThemeJSONBtn.addEventListener('click', function(){
|
|
||||||
if (SaveThemeToJSONInput.value.length > 0) {
|
|
||||||
navigator.clipboard.writeText(SaveThemeToJSONInput.value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let CurrencyDate =
|
|
||||||
LoadFile(chrome.runtime.getURL('js/resources/currencies.json'), function(text){
|
|
||||||
CurrencyDate = new Date(JSON.parse(text).Date).toLocaleDateString("en-US", {day:"numeric",month:"long",year:"numeric"})
|
|
||||||
|
|
||||||
document.getElementById('IRLPriceWithCurrencyCurrency').previousElementSibling.children[1].innerText = document.getElementById('IRLPriceWithCurrencyCurrency').previousElementSibling.children[1].innerText.replace('[DATE]', CurrencyDate)
|
|
||||||
})
|
|
||||||
|
|
||||||
function LoadThemeJSON(string) {
|
function LoadThemeJSON(string) {
|
||||||
try {
|
try {
|
||||||
let JSONTable = JSON.parse(string)
|
let JSONTable = JSON.parse(string);
|
||||||
if (JSONTable.length === ExpectedSettings.ThemeCreator.length) {
|
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) {
|
if (confirm("Are you sure you'd like to replace this theme with the theme specified in the JSON?") === true) {
|
||||||
LoadThemeFromJSONBtn.previousElementSibling.value = ''
|
LoadThemeFromJSONBtn.previousElementSibling.value = '';
|
||||||
document.getElementById('ThemeCreator-Modal').close()
|
document.getElementById('ThemeCreator-Modal').close();
|
||||||
Settings.ThemeCreator = MergeObjects(JSONTable, ExpectedSettings.ThemeCreator)
|
for (let i = 0; i < JSONTable.length; i++) {
|
||||||
Save();
|
if (JSONTable[i][0] !== '#') {
|
||||||
console.log(JSONTable.length, JSONTable, 'applied')
|
JSONTable[i] = '';
|
||||||
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].click();
|
}
|
||||||
}
|
}
|
||||||
} else {
|
Settings.ThemeCreator = Utilities.MergeObjects(JSONTable, Utilities.DefaultSettings.ThemeCreator);
|
||||||
alert('JSON is not a theme!')
|
Save();
|
||||||
//LoadThemeFromJSONBtn.innerText = 'JSON is too short or too long!'
|
console.log(JSONTable.length, JSONTable, 'applied');
|
||||||
//setTimeout(function () {LoadThemeFromJSONBtn.innerText = 'Load'}, 1250)
|
document.getElementById('ThemeCreator').getElementsByTagName('button')[1].click();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} else {
|
||||||
alert('JSON is invalid!')
|
alert('JSON is not a theme!');
|
||||||
//LoadThemeFromJSONBtn.innerText = 'JSON is invalid!'
|
}
|
||||||
//setTimeout(function () {LoadThemeFromJSONBtn.innerText = 'Load'}, 1250)
|
} catch (error) {
|
||||||
}
|
alert('JSON is invalid!');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chrome.storage.sync.get(['PolyPlus_AutoAds'], function(result){
|
||||||
|
let AutoAds = result.PolyPlus_AutoAds || [];
|
||||||
|
|
||||||
|
const Modal = document.getElementById("AutoAdBidding-Modal")
|
||||||
|
const AddButton = document.getElementById('auto-ad-bidding-add')
|
||||||
|
|
||||||
|
AddButton.addEventListener('click', async function() {
|
||||||
|
const Page = new DOMParser().parseFromString((await (await fetch('https://polytoria.com/create/ad/' + AddButton.previousElementSibling.value)).text()), 'text/html')
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const AddRow = function(index, info) {
|
||||||
|
const Row = document.createElement('tr')
|
||||||
|
Row.innerHTML = `
|
||||||
|
<th scope="row">${index+1}</th>
|
||||||
|
<td><a href="https://polytoria.com/create/ad/${info.id}">"${info.name}"</a></td>
|
||||||
|
<td class="text-success"><span class="pi">$</span> 150</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-select ignore">
|
||||||
|
<option value="daily" selected>Daily</option>
|
||||||
|
<option value="weekly">Weekly</option>
|
||||||
|
<option value="monthly">Monthly</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div role="group" class="btn-group w-100">
|
||||||
|
<button class="btn btn-success w-25">
|
||||||
|
BID
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-orange w-25">
|
||||||
|
EDIT
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger w-25">
|
||||||
|
DELETE
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function AreIdentical(obj1, obj2) {
|
||||||
|
if (obj1.length !== obj2.length) { return false }
|
||||||
|
return JSON.stringify(obj1) === JSON.stringify(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');
|
||||||
|
} 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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function MergeObjects(obj1, obj2) {
|
fetch(chrome.runtime.getURL('resources/currencies.json'))
|
||||||
var mergedObj = {};
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
// Copy the values from obj1 to the mergedObj
|
throw new Error('Network not ok');
|
||||||
for (var key in obj1) {
|
}
|
||||||
mergedObj[key] = obj1[key];
|
return response.json();
|
||||||
}
|
})
|
||||||
|
.then((data) => {
|
||||||
// Merge the values from obj2 into the mergedObj, favoring obj2 for non-existing keys in obj1
|
const DateText = new Date(data.Date).toLocaleDateString('en-US', {day: 'numeric', month: 'long', year: 'numeric'});
|
||||||
for (var key in obj2) {
|
document.getElementById('IRLPriceWithCurrency-Date').innerText = DateText;
|
||||||
if (!obj1.hasOwnProperty(key)) {
|
})
|
||||||
mergedObj[key] = obj2[key];
|
.catch((error) => {
|
||||||
} else if (obj1[key] !== obj2[key]) {
|
console.log(error);
|
||||||
mergedObj[key] = obj2[key];
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove keys from mergedObj if they are not present in obj2
|
|
||||||
for (var key in mergedObj) {
|
|
||||||
if (!obj2.hasOwnProperty(key)) {
|
|
||||||
delete mergedObj[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mergedObj;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function MergeObjects(obj1, obj2) {
|
chrome.storage.local.get(['PolyPlus_OutOfDate', 'PolyPlus_LiveVersion', 'PolyPlus_ReleaseNotes', 'PolyPlus_SkipUpdate'], function (result) {
|
||||||
var mergedObj = {};
|
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]);
|
||||||
|
|
||||||
// Copy the values from obj1 to the mergedObj
|
const SkipButton = document.getElementById('skip-this-update');
|
||||||
for (var key in obj1) {
|
SkipButton.addEventListener('click', function () {
|
||||||
mergedObj[key] = obj1[key];
|
Banner.remove();
|
||||||
}
|
chrome.storage.local.set({PolyPlus_SkipUpdate: result.PolyPlus_LiveVersion}, function () {
|
||||||
|
console.log('set skip update to live version: ', result.PolyPlus_LiveVersion);
|
||||||
// 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'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadFile(path, callback) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.onload = function () { return callback(this.responseText); }
|
|
||||||
xhr.open("GET", path, true);
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||