Compare commits
187 commits
release-1.
...
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 |
37 changed files with 4003 additions and 2570 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
.DS_Store
|
||||
manifest.json
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
html,
|
||||
body,
|
||||
#page {
|
||||
/*
|
||||
background: #202020;
|
||||
color: #fff;
|
||||
*/
|
||||
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;
|
||||
|
|
@ -43,7 +39,7 @@ h2 span.indent {
|
|||
}
|
||||
|
||||
.setting-container:not(:last-child) {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.setting-container .title {
|
||||
|
|
@ -51,10 +47,31 @@ h2 span.indent {
|
|||
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;
|
||||
|
|
@ -101,12 +118,9 @@ dialog .modal-body p:first-child {
|
|||
}
|
||||
|
||||
.setting-container.enabled .indicator { background-color: #007bff;}
|
||||
.setting-container.enabled .title { text-shadow: 0px 1px 3px blue; }
|
||||
.setting-container.disabled .indicator { background-color: orangered; }
|
||||
|
||||
.toggle-btn {
|
||||
float: right;
|
||||
width: 100px;
|
||||
}
|
||||
.setting-container.disabled .title { text-shadow: 0px 1px 3px orangered; }
|
||||
|
||||
.limited-time {
|
||||
background: transparent;
|
||||
|
|
@ -162,7 +176,7 @@ dialog .modal-body p:first-child {
|
|||
blue,
|
||||
green
|
||||
);
|
||||
-webkit-mask:
|
||||
mask:
|
||||
linear-gradient(#fff 0 0) content-box,
|
||||
linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
|
|
@ -171,12 +185,18 @@ dialog .modal-body p:first-child {
|
|||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.warning {
|
||||
.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;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@ body[data-URL^='/create/'] .col.d-flex.align-content-between.flex-wrap {
|
|||
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 {
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden !important;
|
||||
|
|
@ -24,6 +31,14 @@ body[data-URL^='/create/'] .col.d-flex.align-content-between.flex-wrap {
|
|||
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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------ */
|
||||
|
||||
/*
|
||||
|
|
@ -92,3 +107,34 @@ body:has(.polyplus-modal[open]) {
|
|||
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 @@
|
|||
Sync:
|
||||
------------------
|
||||
PolyPlus_Settings: {}
|
||||
PolyPlus_PinnedGames: []
|
||||
PolyPlus_BestFriends: []
|
||||
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
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 |
107
images/firefox-icon.svg
Normal file
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 |
|
|
@ -1,494 +0,0 @@
|
|||
let Utilities;
|
||||
|
||||
const Container = document.querySelector('.container.p-0.p-lg-5')
|
||||
const ItemCache = {
|
||||
24122: {
|
||||
type: "hat",
|
||||
accessoryType: "hat",
|
||||
name: "Polytoria Cap",
|
||||
price: 0,
|
||||
creator: {
|
||||
name: "Polytoria",
|
||||
id: 1
|
||||
},
|
||||
thumbnail: "https://c0.ptacdn.com/thumbnails/assets/RR0VPd5hX30Fx5APwRBGObotf1xD1DRT.png",
|
||||
asset: "https://c0.ptacdn.com/assets/InBsL5bpJdp84ZPZGQMeHuyCBlo-uOv7.glb"
|
||||
},
|
||||
24118: {
|
||||
type: "shirt",
|
||||
name: "Green Polytoria Flannel",
|
||||
price: 0,
|
||||
creator: {
|
||||
name: "Polytoria",
|
||||
id: 1
|
||||
},
|
||||
thumbnail: "https://c0.ptacdn.com/thumbnails/assets/s7l57JugjbZfWTKAQ0cqTohOBraRbX5E.png",
|
||||
asset: "https://c0.ptacdn.com/assets/uWrrnFGwgNN5W171vqYTWY7E639rKiXK.png"
|
||||
},
|
||||
24123: {
|
||||
type: "pants",
|
||||
name: "Jeans",
|
||||
price: 0,
|
||||
creator: {
|
||||
name: "Polytoria",
|
||||
id: 1
|
||||
},
|
||||
thumbnail: "https://c0.ptacdn.com/thumbnails/assets/anebTuFMLg8NKhRL3ab7hbzCfmcsFqGO.png",
|
||||
asset: "https://c0.ptacdn.com/assets/HD6TFdXD8CaflRNmd84VCNyNsmTB0SH3.png"
|
||||
}
|
||||
}
|
||||
let Avatar = {
|
||||
useCharacter: true,
|
||||
items: [24122],
|
||||
shirt: 24118,
|
||||
pants: 24123,
|
||||
headColor: '#e0e0e0',
|
||||
torsoColor: '#e0e0e0',
|
||||
leftArmColor: '#e0e0e0',
|
||||
rightArmColor: '#e0e0e0',
|
||||
leftLegColor: '#e0e0e0',
|
||||
rightLegColor: '#e0e0e0'
|
||||
};
|
||||
|
||||
/* Discovery */
|
||||
let Page = 1
|
||||
let Search = ""
|
||||
let TabSelected = "hat"
|
||||
|
||||
!(async () => {
|
||||
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
||||
Settings = result.PolyPlus_Settings || Utilities.DefaultSettings;
|
||||
|
||||
if (Settings.AvatarSandboxOn || 1 === 1) {
|
||||
if (new URLSearchParams(window.location.search).has('sandbox')) {
|
||||
document.title = 'Poly+ Avatar Sandbox'
|
||||
PageLoad()
|
||||
} else {
|
||||
const SandboxButton = document.createElement('a');
|
||||
SandboxButton.classList = 'btn btn-outline-success w-100 mt-3';
|
||||
SandboxButton.href = '?sandbox=true';
|
||||
SandboxButton.innerHTML = '<i class="fas fa-shirt"></i> Avatar Sandbox';
|
||||
document.getElementById('cont-move').parentElement.appendChild(SandboxButton);
|
||||
}
|
||||
}
|
||||
})
|
||||
})();
|
||||
|
||||
async function PageLoad() {
|
||||
const PageContents = (await ((await fetch(chrome.runtime.getURL('resources/avatar-sandbox.html'))).text()))
|
||||
Container.innerHTML = PageContents
|
||||
Utilities.InjectResource("registerTooltips")
|
||||
|
||||
IFrame = document.getElementById('viewFrame')
|
||||
|
||||
UpdateAvatar()
|
||||
LoadItems()
|
||||
|
||||
const Tabs = document.getElementById('tabs')
|
||||
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;
|
||||
LoadItems();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const ClearButton = document.getElementById('clear');
|
||||
ClearButton.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();
|
||||
});
|
||||
|
||||
const LoadMyselfButton = document.getElementById('myself');
|
||||
LoadMyselfButton.addEventListener('click', function () {
|
||||
LoadUser(JSON.parse(window.localStorage.getItem('p+account_info')).ID);
|
||||
});
|
||||
|
||||
const JSONUploadButton = document.getElementById('jsonUpload');
|
||||
JSONUploadButton.addEventListener('change', function () {
|
||||
const Reader = new FileReader();
|
||||
Reader.addEventListener('loadend', function () {
|
||||
Avatar = JSON.parse(Reader.result);
|
||||
UpdateAvatar();
|
||||
|
||||
JSONUploadButton.value = '';
|
||||
});
|
||||
|
||||
Reader.readAsText(JSONUploadButton.files[0]);
|
||||
});
|
||||
|
||||
const JSONSaveButton = document.getElementById('jsonSave');
|
||||
JSONSaveButton.addEventListener('click', function () {
|
||||
const 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);
|
||||
});
|
||||
|
||||
const OpenInNewTabButton = document.getElementById('openNewTab');
|
||||
OpenInNewTabButton.addEventListener('click', function () {
|
||||
window.open(IFrame, "_blank")
|
||||
});
|
||||
|
||||
const LoadAsset = document.getElementById('load-asset')
|
||||
const LoadAssetType = document.getElementById('load-asset-type')
|
||||
LoadAsset.addEventListener('click', function(){
|
||||
const SelectedType = LoadAssetType.options[LoadAssetType.selectedIndex].value
|
||||
|
||||
if (SelectedType !== 'user') {
|
||||
if (SelectedType === 'hat') {
|
||||
Avatar.items.push(LoadAsset.previousElementSibling.value);
|
||||
} else {
|
||||
Avatar[SelectedType] = parseInt(LoadAsset.previousElementSibling.value)
|
||||
}
|
||||
UpdateAvatar();
|
||||
} else {
|
||||
LoadUser(LoadAsset.previousElementSibling.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function UpdateAvatar() {
|
||||
// Hats, Tools: https://api.polytoria.com/v1/assets/serve-mesh/ID
|
||||
// or: https://api.polytoria.com/v1/assets/serve/ID/Asset
|
||||
|
||||
const FormattedAvatar = structuredClone(Avatar)
|
||||
|
||||
const AccessoryPromise = [...Avatar.items, Avatar.tool].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:')).map(async (x, index) => {
|
||||
if (ItemCache[x] === undefined) {
|
||||
const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json())
|
||||
ItemCache[x] = {
|
||||
type: ItemDetails.type,
|
||||
name: ItemDetails.name,
|
||||
price: ItemDetails.price,
|
||||
creator: {
|
||||
name: ItemDetails.creator.name,
|
||||
id: ItemDetails.creator.id
|
||||
},
|
||||
thumbnail: ItemDetails.thumbnail,
|
||||
asset: undefined
|
||||
}
|
||||
|
||||
if (ItemDetails.type === 'hat') {
|
||||
ItemCache[x].accessoryType = ItemDetails.accessoryType
|
||||
}
|
||||
}
|
||||
|
||||
if (ItemCache[x].asset === undefined) {
|
||||
const MeshURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + x)).json())
|
||||
if (MeshURL.success) {
|
||||
ItemCache[x].asset = MeshURL.url
|
||||
if (ItemCache[x].type === 'hat') {
|
||||
FormattedAvatar.items[index] = MeshURL.url
|
||||
} else {
|
||||
FormattedAvatar[ItemCache[x].type] = MeshURL.url
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ItemCache[x].type === 'hat') {
|
||||
FormattedAvatar.items[index] = ItemCache[x].asset
|
||||
} else {
|
||||
FormattedAvatar[ItemCache[x].type] = ItemCache[x].asset
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const TexturePromise = [Avatar.shirt, Avatar.pants, Avatar.face].filter((x) => x !== undefined && !x.toString().startsWith('http') && !x.toString().startsWith('data:') && x !== undefined).map(async (x, index) => {
|
||||
if (ItemCache[x] === undefined) {
|
||||
const ItemDetails = (await (await fetch('https://api.polytoria.com/v1/store/' + x)).json())
|
||||
ItemCache[x] = {
|
||||
type: ItemDetails.type,
|
||||
name: ItemDetails.name,
|
||||
price: ItemDetails.price,
|
||||
creator: {
|
||||
name: ItemDetails.creator.name,
|
||||
id: ItemDetails.creator.id
|
||||
},
|
||||
thumbnail: ItemDetails.thumbnail,
|
||||
asset: undefined
|
||||
}
|
||||
|
||||
if (ItemDetails.price === 0) {
|
||||
if (ItemDetails.sales === 0) {
|
||||
ItemCache[x].price = null
|
||||
} else {
|
||||
ItemCache[x].price = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ItemCache[x].asset === undefined) {
|
||||
const TextureURL = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + x + '/Asset')).json())
|
||||
if (TextureURL.success) {
|
||||
ItemCache[x].asset = TextureURL.url
|
||||
if (x === Avatar.shirt) {
|
||||
FormattedAvatar.shirt = TextureURL.url
|
||||
} else if (x === Avatar.pants) {
|
||||
FormattedAvatar.pants = TextureURL.url
|
||||
} else if (x === Avatar.face) {
|
||||
FormattedAvatar.face = TextureURL.url
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (x === Avatar.shirt) {
|
||||
FormattedAvatar.shirt = ItemCache[x].asset
|
||||
} else if (x === Avatar.pants) {
|
||||
FormattedAvatar.pants = ItemCache[x].asset
|
||||
} else if (x === Avatar.face) {
|
||||
FormattedAvatar.face = ItemCache[x].asset
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (Avatar.face === undefined) {
|
||||
FormattedAvatar.face = "https://c0.ptacdn.com/static/3dview/DefaultFace.png"
|
||||
}
|
||||
|
||||
await Promise.all(AccessoryPromise)
|
||||
await Promise.all(TexturePromise)
|
||||
|
||||
console.log('Real Avatar: ', Avatar)
|
||||
console.log('Formatted: ', FormattedAvatar)
|
||||
IFrame.addEventListener('load', function(){
|
||||
IFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)))
|
||||
})
|
||||
IFrame.src = 'about:blank'
|
||||
|
||||
UpdateBodyColors()
|
||||
LoadWearing()
|
||||
}
|
||||
|
||||
function LoadUser(id) {
|
||||
fetch('https://api.polytoria.com/v1/users/' + id + '/avatar')
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
Avatar.items = [];
|
||||
|
||||
data.assets.forEach((item) => {
|
||||
ItemCache[item.id] = {
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
price: null,
|
||||
creator: null,
|
||||
thumbnail: item.thumbnail,
|
||||
asset: item.path
|
||||
}
|
||||
|
||||
if (item.type === 'hat' || item.type === 'tool') {
|
||||
ItemCache[item.id].creator = {
|
||||
id: 1,
|
||||
name: "Polytoria"
|
||||
}
|
||||
}
|
||||
|
||||
if (item.type === 'hat') {
|
||||
ItemCache[item.id].accessoryType = item.accessoryType
|
||||
Avatar.items.push(item.id)
|
||||
} else {
|
||||
Avatar[item.type] = item.id
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
async function LoadItems() {
|
||||
document.getElementById('inventory').innerHTML = ''
|
||||
|
||||
const Items = (await (await fetch('https://api.polytoria.com/v1/store?limit=12&order=desc&sort=createdAt&showOffsale=true&types[]='+ TabSelected +'&search=' + Search + '&page=' + Page)).json()).assets
|
||||
Items.forEach(item => {
|
||||
const ItemColumn = document.createElement('div')
|
||||
ItemColumn.classList = 'col-auto'
|
||||
ItemColumn.innerHTML = `
|
||||
<div style="max-width: 150px;">
|
||||
<div class="card mb-2 avatar-item-container">
|
||||
<div class="p-2">
|
||||
<img src="${item.thumbnail}" class="img-fluid">
|
||||
${ (item.type === 'hat') ? `
|
||||
<span class="position-absolute" style="top: 5px; left: 5px; z-index: 1;">
|
||||
<span class="badge bg-secondary">${CleanAccessoryType(item.accessoryType)}</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/${item.id}" class="text-reset">
|
||||
<h6 class="text-truncate mb-0">${item.name}</h6>
|
||||
</a>
|
||||
<small class="text-muted d-block text-truncate">
|
||||
by <a href="/users/${ (item.type !== 'hat' && item.type !== 'tool') ? '1' : item.creator.id }" class="text-reset">${ (item.type !== 'hat' && item.type !== 'tool') ? 'Polytoria' : item.creator.name }</a>
|
||||
</small>
|
||||
</div>
|
||||
`
|
||||
document.getElementById('inventory').appendChild(ItemColumn)
|
||||
|
||||
ItemCache[item.id] = {
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
price: item.price,
|
||||
creator: {
|
||||
name: item.creator.name,
|
||||
id: item.creator.id
|
||||
},
|
||||
thumbnail: item.thumbnail,
|
||||
asset: undefined
|
||||
}
|
||||
|
||||
if (item.price === 0) {
|
||||
if (item.sales === 0) {
|
||||
console.log("ITEM IS AWARD-ONLY!!! ", item)
|
||||
ItemCache[item.id].price = null
|
||||
} else {
|
||||
ItemCache[item.id].price = 0
|
||||
}
|
||||
}
|
||||
|
||||
if (item.type === 'hat') {
|
||||
ItemCache[item.id].accessoryType = item.accessoryType
|
||||
}
|
||||
|
||||
ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){
|
||||
WearAsset(item)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function LoadWearing() {
|
||||
document.getElementById('wearing').innerHTML = '';
|
||||
[...Avatar.items, Avatar.shirt, Avatar.pants].filter((x) => x !== undefined).forEach(id => {
|
||||
const Cached = Object.values(ItemCache)[Object.keys(ItemCache).indexOf(id.toString())]
|
||||
if (Cached !== undefined) {
|
||||
if (Cached.creator === null) {
|
||||
Cached.creator = {
|
||||
id: 1,
|
||||
name: "-"
|
||||
}
|
||||
}
|
||||
|
||||
if (Cached.price === null) { Cached.price = "???" }
|
||||
|
||||
const ItemColumn = document.createElement('div')
|
||||
ItemColumn.classList = 'col-auto'
|
||||
ItemColumn.innerHTML = `
|
||||
<div style="max-width: 150px;">
|
||||
<div class="card mb-2 avatar-item-container">
|
||||
<div class="p-2">
|
||||
<img src="${Cached.thumbnail}" class="img-fluid">
|
||||
${ (Cached.type === 'hat') ? `
|
||||
<span class="position-absolute" style="top: 5px; left: 5px; z-index: 1;">
|
||||
<span class="badge bg-secondary">${CleanAccessoryType(Cached.accessoryType)}</span>
|
||||
</span>
|
||||
` : ''}
|
||||
<button class="avatarAction btn btn-danger btn-sm position-absolute rounded-circle text-center" style="top: -10px; right: -16px; width: 32px; height: 32px; z-index: 1;"><i class="fas fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/store/${id}" class="text-reset">
|
||||
<h6 class="text-truncate mb-0">${Cached.name}</h6>
|
||||
</a>
|
||||
<small class="text-muted d-block text-truncate">
|
||||
by <a href="/users/${Cached.creator.id || "1"}" class="text-reset">${Cached.creator.name || "-"}</a>
|
||||
</small>
|
||||
<small style="font-size: 0.8rem;" class="d-block text-truncate
|
||||
${ (Cached.price === 0) ? 'text-primary">Free' : (Cached.price !== "???") ? 'text-success"><i class="pi mr-1">$</i> ' + Cached.price : 'text-muted">???</small>' }
|
||||
</small>
|
||||
</div>
|
||||
`
|
||||
document.getElementById('wearing').appendChild(ItemColumn)
|
||||
|
||||
ItemColumn.getElementsByClassName('p-2')[0].addEventListener('click', function(){
|
||||
WearAsset(Cached)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function WearAsset(details) {
|
||||
if (Avatar[details.type] !== details.id && Avatar.items.indexOf(details.id) === -1) {
|
||||
// Equip
|
||||
if (details.type === 'hat') {
|
||||
Avatar.items.push(details.id)
|
||||
} else {
|
||||
Avatar[details.type] = details.id
|
||||
}
|
||||
} else {
|
||||
// Unequip
|
||||
if (details.type === 'hat') {
|
||||
Avatar.items.splice(Avatar.items.indexOf(details.id), 1);
|
||||
} else {
|
||||
Avatar[details.type] = undefined
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAvatar()
|
||||
LoadWearing()
|
||||
}
|
||||
|
||||
function UpdateBodyColors() {
|
||||
const BodyColors = {
|
||||
head: Avatar.headColor,
|
||||
torso: Avatar.torsoColor,
|
||||
leftArm: Avatar.leftArmColor,
|
||||
rightArm: Avatar.rightArmColor,
|
||||
leftLeg: Avatar.leftLegColor,
|
||||
rightLeg: Avatar.rightLegColor
|
||||
}
|
||||
|
||||
Object.keys(BodyColors).forEach((elementID, i) => {
|
||||
document.getElementById(elementID).style.backgroundColor = Object.values(BodyColors)[i]
|
||||
})
|
||||
}
|
||||
|
||||
function CleanAccessoryType(type) {
|
||||
const CleanAccessoryTypes = {
|
||||
hat: "Hat",
|
||||
backAccessory: "Back Accessory",
|
||||
faceAccessory: "Face Accessory",
|
||||
headAttachment: "Head Attachment",
|
||||
hair: "Hair",
|
||||
neckAccessory: "Neck Accessory",
|
||||
headCover: "Head Cover",
|
||||
headAccessory: "Head Accessory"
|
||||
}
|
||||
return Object.values(CleanAccessoryTypes)[Object.keys(CleanAccessoryTypes).indexOf(type)] || "!!!"+type
|
||||
}
|
||||
1296
js/account/avatar-sandbox.js
Executable file → Normal file
1296
js/account/avatar-sandbox.js
Executable file → Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,538 +0,0 @@
|
|||
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID;
|
||||
const BodyColors = [
|
||||
'#f8f8f8',
|
||||
'#cdcdcd',
|
||||
'#111111',
|
||||
'#ff0000',
|
||||
'#a34b4b',
|
||||
'#ffc9c9',
|
||||
'#957977',
|
||||
'#c4281c',
|
||||
'#da867a',
|
||||
'#694028',
|
||||
'#cc8e69',
|
||||
'#a05f35',
|
||||
'#7c5c46',
|
||||
'#eab892',
|
||||
'#da8541',
|
||||
'#aa5500',
|
||||
'#ffcc99',
|
||||
'#e29b40',
|
||||
'#ffaf00',
|
||||
'#ffb000',
|
||||
'#d7c59a',
|
||||
'#f5cd30',
|
||||
'#fdea8d',
|
||||
'#e5e4df',
|
||||
'#c1be42',
|
||||
'#ffff00',
|
||||
'#ffffcc',
|
||||
'#a4bd47',
|
||||
'#7f8e64',
|
||||
'#a1c48c',
|
||||
'#3a7d15',
|
||||
'#4b974b',
|
||||
'#00ff00',
|
||||
'#ccffcc',
|
||||
'#27462d',
|
||||
'#287f47',
|
||||
'#789082',
|
||||
'#9ff3e9',
|
||||
'#12eed4',
|
||||
'#f2f3f3',
|
||||
'#00ffff',
|
||||
'#008f9c',
|
||||
'#04afec',
|
||||
'#80bbdb',
|
||||
'#b4d2e4',
|
||||
'#0d69ac',
|
||||
'#1b2a35',
|
||||
'#afddff',
|
||||
'#6e99ca',
|
||||
'#74869d',
|
||||
'#2154b9',
|
||||
'#002060',
|
||||
'#0000ff',
|
||||
'#b1a7ff',
|
||||
'#a3a2a5',
|
||||
'#6225d1',
|
||||
'#b480ff',
|
||||
'#8c5b9f',
|
||||
'#6b327c',
|
||||
'#aa00aa',
|
||||
'#635f62',
|
||||
'#ff00bf',
|
||||
'#ff66cc',
|
||||
'#e8bac8'
|
||||
];
|
||||
|
||||
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'
|
||||
};
|
||||
|
||||
if (new URLSearchParams(window.location.search).has('sandbox')) {
|
||||
console.log('Avatar Sandbox!');
|
||||
|
||||
LoadFile(chrome.runtime.getURL('resources/avatar-sandbox.html'), function (html) {
|
||||
PageContainer.innerHTML = html;
|
||||
ItemGrid = document.getElementById('inventory');
|
||||
Wearing = document.getElementById('wearing');
|
||||
Tabs = document.getElementById('tabs');
|
||||
IFrame = document.getElementById('viewFrame');
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
let LoadAsset = document.getElementById('load-asset');
|
||||
const LoadAssetType = document.getElementById('load-asset-type')
|
||||
LoadAsset.addEventListener('click', async function () {
|
||||
if (!LoadAsset.previousElementSibling.value.startsWith('http') && !LoadAsset.previousElementSibling.value.startsWith('data:')) {
|
||||
if (LoadAssetType.options[LoadAssetType.selectedIndex].value === 'hat') {
|
||||
Avatar.items.push((await (await fetch('https://api.polytoria.com/v1/assets/serve-mesh/' + LoadAsset.previousElementSibling.value)).json()).url);
|
||||
} else {
|
||||
Avatar[LoadAssetType.options[LoadAssetType.selectedIndex].value] = (await (await fetch('https://api.polytoria.com/v1/assets/serve/' + LoadAsset.previousElementSibling.value + '/Asset')).json()).url;
|
||||
}
|
||||
} else {
|
||||
if (LoadAssetType.options[LoadAssetType.selectedIndex].value === 'hat') {
|
||||
Avatar.items.push(LoadAsset.previousElementSibling.value);
|
||||
} else {
|
||||
Avatar[LoadAssetType.options[LoadAssetType.selectedIndex].value] = LoadAsset.previousElementSibling.value
|
||||
}
|
||||
}
|
||||
UpdateAvatar();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const SandboxButton = document.createElement('a');
|
||||
SandboxButton.classList = 'btn btn-outline-success w-100 mt-3';
|
||||
SandboxButton.href = '?sandbox=true';
|
||||
SandboxButton.innerHTML = '<i class="fas fa-shirt"></i> Avatar Sandbox';
|
||||
document.getElementById('cont-move').parentElement.appendChild(SandboxButton);
|
||||
}
|
||||
|
||||
function UpdateAvatar() {
|
||||
FormatAvatar().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.setAttribute('data-id', item.id);
|
||||
NewItemCard.classList = 'col-auto';
|
||||
NewItemCard.innerHTML = `
|
||||
<div style="max-width: 150px;">
|
||||
<div class="card mb-2 avatar-item-container">
|
||||
<div class="p-2">
|
||||
<img src="${item.thumbnail}" class="img-fluid">
|
||||
<span class="position-absolute" style="top: 5px; left: 5px; z-index: 1;">
|
||||
<span class="badge bg-secondary">${item.type.charAt(0).toUpperCase() + item.type.substring(1)}</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/${item.id}" class="text-reset">
|
||||
<h6 class="text-truncate mb-0">${item.name}</h6>
|
||||
</a>
|
||||
<small class="text-muted d-block text-truncate">
|
||||
by <a href="/users/${item.creator.id}" class="text-reset">${item.creator.name}</a>
|
||||
</small>
|
||||
</div>
|
||||
`;
|
||||
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
|
||||
WearAsset(NewItemCard, item);
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
const meshPromises = Avatar.items.map(async (item, index) => {
|
||||
if (typeof item === 'number') {
|
||||
console.log(item);
|
||||
FormattedAvatar.items[index] = await FetchMesh(item)
|
||||
console.log('after url');
|
||||
//Avatar.items[index] = URL
|
||||
}
|
||||
});
|
||||
|
||||
Avatar.items.forEach(async (item, index) => {
|
||||
if (typeof item === 'number') {
|
||||
console.log(item);
|
||||
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 === undefined) { FormattedAvatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png'; }
|
||||
if (FormattedAvatar.face && typeof FormattedAvatar.face === 'number') {
|
||||
FormattedAvatar.face = await FetchAsset(FormattedAvatar.face);
|
||||
} else if (FormattedAvatar.face === undefined) {
|
||||
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);
|
||||
}
|
||||
|
||||
await Promise.all(meshPromises)
|
||||
|
||||
console.log('Real Avatar: ', Avatar)
|
||||
console.log('Formatted: ', FormattedAvatar)
|
||||
console.log('URI: ', btoa(encodeURIComponent(JSON.stringify(FormattedAvatar))))
|
||||
console.log('Fix: ', JSON.stringify(decodeURIComponent(atob(btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)))))));
|
||||
return btoa(encodeURIComponent(JSON.stringify(FormattedAvatar)));
|
||||
}
|
||||
|
||||
function LoadMyself() {
|
||||
fetch('https://api.polytoria.com/v1/users/:id/avatar'.replace(':id', UserID))
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
Avatar.items = [];
|
||||
|
||||
data.assets.forEach((item) => {
|
||||
switch (item.type) {
|
||||
case 'hat':
|
||||
Avatar.items.push(item.id);
|
||||
break;
|
||||
default:
|
||||
Avatar[item.type] = item.id;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
Avatar.headColor = '#' + data.colors.head || '#cdcdcd';
|
||||
Avatar.torsoColor = '#' + data.colors.torso || '#cdcdcd';
|
||||
Avatar.leftArmColor = '#' + data.colors.leftArm || '#cdcdcd';
|
||||
Avatar.rightArmColor = '#' + data.colors.rightArm || '#cdcdcd';
|
||||
Avatar.leftLegColor = '#' + data.colors.leftLeg || '#cdcdcd';
|
||||
Avatar.rightLegColor = '#' + data.colors.rightLeg || '#cdcdcd';
|
||||
|
||||
UpdateAvatar();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function WearAsset(element, info) {
|
||||
if (Avatar.items.indexOf(info.id) === -1 && Avatar[info.type] !== info.id) {
|
||||
console.log('Equip', info);
|
||||
switch (info.type) {
|
||||
case 'hat':
|
||||
Avatar.items.push(info.id);
|
||||
break;
|
||||
default:
|
||||
Avatar[info.type] = info.id;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
console.log('unequip', info);
|
||||
switch (info.type) {
|
||||
case 'hat':
|
||||
Avatar.items.splice(Avatar.items.indexOf(info.id), 1);
|
||||
break;
|
||||
case 'face':
|
||||
Avatar.face = 'https://c0.ptacdn.com/static/3dview/DefaultFace.png';
|
||||
break;
|
||||
default:
|
||||
Avatar[info.type] = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const ToggleButton = element.getElementsByClassName('avatarAction')[0];
|
||||
ToggleButton.classList.toggle('btn-success');
|
||||
ToggleButton.classList.toggle('btn-danger');
|
||||
ToggleButton.children[0].classList.toggle('fa-plus');
|
||||
ToggleButton.children[0].classList.toggle('fa-minus');
|
||||
|
||||
const Duplicate = ItemGrid.querySelector(`[data-id="${info.id}"]`);
|
||||
if (Duplicate !== null && Duplicate !== element) {
|
||||
const DuplicateToggleButton = Duplicate.getElementsByClassName('avatarAction')[0];
|
||||
DuplicateToggleButton.classList.toggle('btn-success');
|
||||
DuplicateToggleButton.classList.toggle('btn-danger');
|
||||
DuplicateToggleButton.children[0].classList.toggle('fa-plus');
|
||||
DuplicateToggleButton.children[0].classList.toggle('fa-minus');
|
||||
}
|
||||
|
||||
LoadWearing();
|
||||
UpdateAvatar();
|
||||
}
|
||||
|
||||
async function FetchMesh(id) {
|
||||
if (id === null) {
|
||||
return null;
|
||||
}
|
||||
console.log('https://api.polytoria.com/v1/assets/serve-mesh/:id'.replace(':id', id));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
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);
|
||||
resolve(data.url);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Fetch error: ' + error);
|
||||
});
|
||||
})
|
||||
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.setAttribute('data-id', item.id);
|
||||
NewItemCard.classList = 'col-auto';
|
||||
NewItemCard.innerHTML = `
|
||||
<div style="max-width: 150px;">
|
||||
<div class="card mb-2 avatar-item-container">
|
||||
<div class="p-2">
|
||||
<img src="${item.thumbnail}" class="img-fluid">
|
||||
<span class="position-absolute" style="top: 5px; left: 5px; z-index: 1;">
|
||||
<span class="badge bg-secondary">${item.type.charAt(0).toUpperCase() + item.type.substring(1)}</span>
|
||||
</span>
|
||||
<button class="avatarAction btn btn-danger btn-sm position-absolute rounded-circle text-center" style="top: -10px; right: -16px; width: 32px; height: 32px; z-index: 1;"><i class="fas fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/store/${item.id}" class="text-reset">
|
||||
<h6 class="text-truncate mb-0">${item.name}</h6>
|
||||
</a>
|
||||
<small class="text-muted d-block text-truncate">
|
||||
by <a href="/users/${item.creator.id}" class="text-reset">${item.creator.name}</a>
|
||||
</small>
|
||||
</div>
|
||||
`;
|
||||
Wearing.appendChild(NewItemCard);
|
||||
NewItemCard.getElementsByClassName('p-2')[0].addEventListener('click', function () {
|
||||
WearAsset(NewItemCard, item);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Fetch error: ' + error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (Array.from(Wearing.children).length === 0) {
|
||||
Wearing.innerHTML = 'No items to show.';
|
||||
}
|
||||
}
|
||||
300
js/account/home.js
Executable file → Normal file
300
js/account/home.js
Executable file → Normal file
|
|
@ -1,194 +1,99 @@
|
|||
/*
|
||||
this file needs a rewrite by me lol
|
||||
*/
|
||||
|
||||
var Settings;
|
||||
var PinnedGamesData;
|
||||
var BestFriendsData;
|
||||
|
||||
let Utilities;
|
||||
|
||||
(async () => {
|
||||
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
||||
Settings = Utilities.MergeObjects(result.PolyPlus_Settings || Utilities.DefaultSettings);
|
||||
|
||||
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||
IRLPrice();
|
||||
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames'], async function(result){
|
||||
Settings = result.PolyPlus_Settings || {
|
||||
PinnedGamesOn: true
|
||||
}
|
||||
|
||||
if (Settings.HomeFriendCountOn === true) {
|
||||
ShowFriendCount();
|
||||
if (Settings.PinnedGamesOn === true) {
|
||||
const PlaceIDs = result.PolyPlus_PinnedGames || [];
|
||||
chrome.storage.local.get(['PolyPlus_PinnedGamesData'], async function(result){
|
||||
let PinnedGamesData = result['PolyPlus_PinnedGamesData'] || {data:undefined};
|
||||
|
||||
const PinnedGamesContainer = document.createElement('div')
|
||||
PinnedGamesContainer.innerHTML = `
|
||||
<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>
|
||||
`
|
||||
|
||||
const RightSideColumn = document.getElementsByClassName('col-lg-8')[0];
|
||||
if (document.getElementsByClassName('home-event-container')[0] === undefined) {
|
||||
RightSideColumn.insertBefore(PinnedGamesContainer, RightSideColumn.children[0]);
|
||||
} else {
|
||||
RightSideColumn.insertBefore(PinnedGamesContainer, RightSideColumn.children[1]);
|
||||
}
|
||||
|
||||
if (Settings.PinnedGamesOn === true || Settings.BestFriendsOn === true) {
|
||||
Update();
|
||||
// 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
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
let ContainerElement = `
|
||||
<div class="card-body p-0 m-1 scrollFadeContainer d-flex"></div>`;
|
||||
let GameContainerElement = `
|
||||
chrome.storage.local.set({['PolyPlus_PinnedGamesData']: {
|
||||
data: PinnedGamesData.data,
|
||||
requested: new Date().getTime()
|
||||
}}, function(){});
|
||||
}
|
||||
|
||||
const PinnedGamesCard = document.getElementById('p+pinned_games_card')
|
||||
for (let i = 0; i < PlaceIDs.length; i++) {
|
||||
const PlaceID = PlaceIDs.toSorted((a, b) => b - a)[i]
|
||||
const PlaceDetails = PinnedGamesData.data[PlaceID]
|
||||
|
||||
const PlaceCard = document.createElement('a')
|
||||
PlaceCard.classList = 'd-none'
|
||||
PlaceCard.href = '/places/' + PlaceID
|
||||
PlaceCard.innerHTML = `
|
||||
<div class="scrollFade card me-2 place-card force-desktop text-center mb-2" style="opacity: 1;">
|
||||
<div class="card-body">
|
||||
<div class="ratings-header">
|
||||
<img src=":Thumbnail" class="place-card-image" style="position: relative;">
|
||||
<div style="position: absolute;background: linear-gradient(to bottom, black, transparent, transparent, transparent);width: 100%;height: 100%;top: 0;left: 0;border-radius: 10px;padding-top: 5px;color: gray;font-size: 0.8rem;">
|
||||
<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>
|
||||
<i id="thumbup-icn" class="thumb-icon far fa-thumbs-up"></i>
|
||||
:Likes
|
||||
</span>
|
||||
|
|
||||
<span>
|
||||
<i id="thumbdown-icn" class="thumb-icon far fa-thumbs-down"></i>
|
||||
:Dislikes
|
||||
${PlaceDetails.playing}
|
||||
Playing
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mt-2 mb-1 place-card-title">
|
||||
:GameName
|
||||
${PlaceDetails.name}
|
||||
</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 mb-3';
|
||||
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%;';
|
||||
|
||||
let Spacer = document.createElement('div');
|
||||
Spacer.innerHTML = ' ';
|
||||
Spacer.style.width = '50px';
|
||||
Spacer.prepend(BestFriendsContainer);
|
||||
|
||||
FriendContainer.prepend(BestFriendsContainer);
|
||||
|
||||
async function Update() {
|
||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
|
||||
PinnedGamesData = result.PolyPlus_PinnedGames.toSorted((a, b) => b - a) || [];
|
||||
|
||||
if (Settings.PinnedGamesOn === true) {
|
||||
PinnedGames();
|
||||
} else {
|
||||
NewContainer.style.display = 'none';
|
||||
NewTitle.style.display = 'none';
|
||||
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()
|
||||
}
|
||||
});
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_BestFriends'], function (result) {
|
||||
BestFriendsData = result.PolyPlus_BestFriends || [];
|
||||
|
||||
if (Settings.BestFriendsOn === true) {
|
||||
BestFriends();
|
||||
} else {
|
||||
BestFriendsContainer.style.display = 'none';
|
||||
Spacer.style.display = 'none';
|
||||
PinnedGamesCard.appendChild(PlaceCard)
|
||||
}
|
||||
PinnedGamesCard.children[0].remove()
|
||||
PinnedGamesCard.classList.add('d-flex')
|
||||
Array.from(PinnedGamesCard.children).forEach((place) => {place.classList.remove('d-none')})
|
||||
});
|
||||
}
|
||||
|
||||
function PinnedGames() {
|
||||
var Existing = NewContainer.children[0].children;
|
||||
Array.from(Existing).forEach((element) => {
|
||||
element.remove();
|
||||
});
|
||||
|
||||
if (PinnedGamesData.length === 0) {
|
||||
NewContainer.style.display = 'none';
|
||||
NewTitle.style.display = 'none';
|
||||
} else {
|
||||
NewContainer.style.display = '';
|
||||
NewTitle.style.display = '';
|
||||
}
|
||||
|
||||
for (let element of PinnedGamesData) {
|
||||
fetch('https://api.polytoria.com/v1/places/' + element)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
let GameName = data.name;
|
||||
let GameThumbnail = data.thumbnail;
|
||||
|
||||
var NewGameContainer = document.createElement('a');
|
||||
NewGameContainer.innerHTML = GameContainerElement.replace(':GameName', GameName)
|
||||
.replace(':Thumbnail', GameThumbnail)
|
||||
.replace(':Likes', data.rating.likes)
|
||||
.replace(':Dislikes', data.rating.dislikes);
|
||||
NewGameContainer.href = '/places/' + element;
|
||||
|
||||
/*
|
||||
if (new Date().getDate() >= new Date(data.updatedAt).getDate()) {
|
||||
console.log('Game has updated')
|
||||
}
|
||||
*/
|
||||
|
||||
NewContainer.children[0].appendChild(NewGameContainer);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function BestFriends() {
|
||||
return
|
||||
Array.from(document.querySelectorAll('[bestFriend]')).forEach((element) => {
|
||||
element.removeAttribute('bestFriend');
|
||||
element.getElementsByClassName('friend-name')[0].style.color = 'initial';
|
||||
FriendContainer.appendChild(element);
|
||||
});
|
||||
|
||||
if (BestFriendsData.length === 0) {
|
||||
BestFriendsContainer.style.visibility = 'hidden';
|
||||
BestFriendsContainer.style.padding = '0px !important';
|
||||
BestFriendsContainer.style.margin = '0px !important';
|
||||
} else {
|
||||
BestFriendsContainer.style.visibility = 'visible';
|
||||
BestFriendsContainer.style.padding = '';
|
||||
BestFriendsContainer.style.margin = '';
|
||||
}
|
||||
|
||||
BestFriendsData.forEach((element) => {
|
||||
let ExistingFriend = document.getElementById('friend-' + element);
|
||||
if (ExistingFriend) {
|
||||
ExistingFriend.setAttribute('bestFriend', 'true');
|
||||
ExistingFriend.getElementsByClassName('friend-name')[0].style.color = 'yellow';
|
||||
BestFriendsContainer.prepend(ExistingFriend);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var SecondaryColumn = document.getElementsByClassName('col-lg-8')[0];
|
||||
if (document.getElementsByClassName('home-event-container')[0] === undefined) {
|
||||
SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[0]);
|
||||
SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[0]);
|
||||
} else {
|
||||
SecondaryColumn.insertBefore(NewContainer, SecondaryColumn.children[1]);
|
||||
SecondaryColumn.insertBefore(NewTitle, SecondaryColumn.children[1]);
|
||||
}
|
||||
|
||||
async function IRLPrice() {
|
||||
if (Settings.IRLPriceWithCurrency && Settings.IRLPriceWithCurrency.Enabled === true) {
|
||||
(async () => {
|
||||
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
|
|
@ -209,21 +114,66 @@ async function IRLPrice() {
|
|||
})();
|
||||
}
|
||||
|
||||
async function ShowFriendCount() {
|
||||
let FriendCount = (await (await fetch('https://polytoria.com/api/friends?page=1')).json()).meta.total;
|
||||
/*
|
||||
const FirstPage = (await (await fetch('https://polytoria.com/api/friends?page=1')).json())
|
||||
if (FirstPage.meta.lastPage > 1) {
|
||||
const LastPage = (await (await fetch('https://polytoria.com/api/friends?page=' + Pages)).json())
|
||||
FriendCount = (12*(FirstPage.meta.pages-1)) + LastPage.data.length
|
||||
} else {
|
||||
FriendCount = FirstPage.data.length
|
||||
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})
|
||||
}
|
||||
})
|
||||
|
|
@ -6,6 +6,8 @@ Username = window.location.pathname.split('/')[2];
|
|||
let UserID;
|
||||
let ItemGrid;
|
||||
|
||||
let _Utilities;
|
||||
|
||||
if (window.location.pathname.split('/')[3] === 'inventory') {
|
||||
!(async () => {
|
||||
UserID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + Username )).json()).id;
|
||||
|
|
@ -14,7 +16,10 @@ if (window.location.pathname.split('/')[3] === 'inventory') {
|
|||
/*
|
||||
Rewritten item wishlist function will take in the data with a parameter instead
|
||||
*/
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result){
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], async function(result){
|
||||
_Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
_Utilities = _Utilities.default
|
||||
|
||||
Settings = result.PolyPlus_Settings
|
||||
|
||||
const Nav = document.getElementsByClassName('nav-pills')[0];
|
||||
|
|
@ -67,6 +72,19 @@ if (window.location.pathname.split('/')[3] === 'inventory') {
|
|||
});
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -265,31 +283,44 @@ async function CollectibleCategory() {
|
|||
Collectibles.push(...InitialInventory.inventory.filter((x) => x.asset.isLimited === true))
|
||||
|
||||
if (InitialInventory.pages > 1) {
|
||||
if (InitialInventory.pages > 3) {
|
||||
InitialInventory.pages = 3
|
||||
if (InitialInventory.pages > 12) {
|
||||
InitialInventory.pages = 12
|
||||
}
|
||||
|
||||
for (let page = 2; i < InitialInventory.pages; i++) {
|
||||
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 => {
|
||||
item = item.asset
|
||||
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.id}" class="text-reset">
|
||||
<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.thumbnail}" class="img-fluid rounded">
|
||||
<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.name}
|
||||
${item.asset.name}
|
||||
</h6>
|
||||
</a>
|
||||
<small class="text-muted d-block mb-1">
|
||||
|
|
@ -298,4 +329,24 @@ async function CollectibleCategory() {
|
|||
`
|
||||
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")
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
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)');
|
||||
|
||||
|
|
@ -16,19 +18,44 @@ if (Username) {
|
|||
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||
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'
|
||||
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(){
|
||||
|
|
@ -84,9 +111,9 @@ if (Username) {
|
|||
const AvatarCard = document.getElementById('user-avatar-card')
|
||||
const ToggleButton = document.createElement('button')
|
||||
ToggleButton.classList = 'btn btn-primary btn-sm 3dviewtoggler isactive'
|
||||
ToggleButton.style = 'position: absolute; right: 15px; margin: 10px;'
|
||||
ToggleButton.style = 'position: absolute; right: 15px; margin-top: 20px;'
|
||||
ToggleButton.innerHTML = '<i class="toggleIcn fad fa-image"></i>'
|
||||
AvatarCard.children[0].insertBefore(ToggleButton, AvatarIFrame)
|
||||
AvatarCard.getElementsByClassName('position-relative')[0].insertBefore(ToggleButton, AvatarIFrame)
|
||||
|
||||
ToggleButton.addEventListener('click', async function(){
|
||||
if (ToggleButton.children[0].classList.contains('fa-image')) {
|
||||
|
|
@ -115,8 +142,12 @@ if (Username) {
|
|||
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'
|
||||
}
|
||||
|
|
@ -129,16 +160,18 @@ if (Username) {
|
|||
}
|
||||
});
|
||||
|
||||
if (new URLSearchParams(window.location.search).get('birthday') === 'true') {
|
||||
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 ${new Date().getFullYear() - new Date(JoinDateRow.children[1].innerText).getFullYear()}rd Polytoria anniversary!
|
||||
<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?anniversary=1" class="btn btn-sm btn-outline-light mt-2"><i class="fas fa-hands-clapping me-1"></i> Send ${UserID.username} congrats</a>
|
||||
<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'))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||
if (result.PolyPlus_Settings.MoreSearchFiltersOn === true) {
|
||||
const BlockedUsersCard = document.getElementsByClassName('card-body')[1];
|
||||
const BlockedUsersCard = document.querySelector('.card-body:has([action^="/api/users/"])');
|
||||
const InputGroup = document.createElement('div');
|
||||
InputGroup.classList = 'input-group mb-2';
|
||||
InputGroup.innerHTML = `
|
||||
|
|
@ -9,9 +9,8 @@ chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
|||
`;
|
||||
BlockedUsersCard.insertBefore(InputGroup, BlockedUsersCard.children[0]);
|
||||
const SearchBar = document.getElementById('blocked-users-search');
|
||||
const ConfirmBtn = document.getElementById('blocked-users-confirm');
|
||||
|
||||
ConfirmBtn.addEventListener('click', function () {
|
||||
SearchBar.addEventListener('input', function () {
|
||||
SearchBlockedUsers(SearchBar.value);
|
||||
});
|
||||
|
||||
|
|
|
|||
105
js/account/trade-valuation.js
Normal file
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")
|
||||
}
|
||||
});
|
||||
})();
|
||||
367
js/background.js
367
js/background.js
|
|
@ -88,7 +88,30 @@ const DefaultSettings = {
|
|||
UserStatsOn: true,
|
||||
LeaderboardsOn: true
|
||||
},
|
||||
CollectibleInventoryCatOn: 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
|
||||
|
|
@ -101,32 +124,76 @@ chrome.runtime.onInstalled.addListener(() => {
|
|||
})
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(async function (request, sender, sendResponse) {
|
||||
let RecordingTimePlayed = false
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
|
||||
if (request.action === 'reload') {
|
||||
chrome.runtime.reload();
|
||||
} else if (request.action === 'greatdivide_stats') {
|
||||
const Statistics = (await (await fetch('https://stats.silly.mom/player_stats?username=' + request.username)).json()).results
|
||||
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: [Statistics]
|
||||
args: [Cache[request.userID].data]
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const LoadStats = function(stats){
|
||||
const GreatDivideCard = document.getElementById('p+greatdivide_card')
|
||||
if (stats !== null) {
|
||||
stats = stats[0]
|
||||
document.getElementById('p+greatdivide_stats').innerHTML = `
|
||||
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()} (${stats.UniqueKills.toLocaleString()} unique)
|
||||
${stats.Kills.toLocaleString()} <small class="text-muted" style="font-size: 0.8rem;">(${stats.UniqueKills.toLocaleString()} unique)</small>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
|
|
@ -143,8 +210,8 @@ chrome.runtime.onMessage.addListener(async function (request, sender, sendRespon
|
|||
<i class="fa-solid fa-percent text-center d-inline-block" style="width:1.2em"></i>
|
||||
Kill Death Ratio
|
||||
</b>
|
||||
<span class="float-end">
|
||||
${(stats.Kills / stats.Deaths).toFixed(4)}
|
||||
<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">
|
||||
|
|
@ -174,7 +241,7 @@ chrome.runtime.onMessage.addListener(async function (request, sender, sendRespon
|
|||
${stats.FlagsCaptured} (${stats.FlagsReturned} returned)
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div>
|
||||
<b>
|
||||
<i class="fa-solid fa-box-open text-center d-inline-block" style="width:1.2em"></i>
|
||||
Airdrops Collected
|
||||
|
|
@ -183,9 +250,186 @@ chrome.runtime.onMessage.addListener(async function (request, sender, sendRespon
|
|||
${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 {
|
||||
document.getElementById('p+greatdivide_stats').innerHTML = "<div class=\"mb-3\">This user hasn't participated in The Great Divide.</div>"
|
||||
ValueCard.innerHTML = `
|
||||
There is no evaluation for this item at this time.
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -196,86 +440,7 @@ chrome.action.onClicked.addListener((tab) => {
|
|||
chrome.tabs.create({active: true, url: SettingsURL});
|
||||
});
|
||||
|
||||
// REGISTER AN ALARM FOR DAILY UPDATE CHECK
|
||||
chrome.alarms.create('PolyPlus-UpdateCheck', {
|
||||
when: Date.now() + GetNext12PM()
|
||||
});
|
||||
|
||||
function GetNext12PM() {
|
||||
const Now = new Date();
|
||||
const Next = new Date();
|
||||
Next.setHours(12, 0, 0, 0);
|
||||
if (Now.getHours() >= 12) {
|
||||
Next.setDate(Next.getDate() + 1);
|
||||
}
|
||||
return Next - Now;
|
||||
}
|
||||
|
||||
// HANDLE ALARMS FIRING
|
||||
/*
|
||||
chrome.alarms.onAlarm.addListener(function (alarm) {
|
||||
if (alarm.name === 'PolyPlus-UpdateCheck') {
|
||||
RunUpdateNotifier();
|
||||
}
|
||||
});
|
||||
*/
|
||||
function RunUpdateNotifier() {
|
||||
chrome.storage.local.get(['PolyPlus_LiveVersion', 'PolyPlus_OutOfDate', 'PolyPlus_SkipUpdate'], function (result) {
|
||||
const OutOfDate = result.PolyPlus_OutOfDate || false;
|
||||
const SkipUpdate = result.PolyPlus_SkipUpdate || null;
|
||||
const LiveVersion = result.PolyPlus_LiveVersion || Manifest.version;
|
||||
if (OutOfDate !== true && SkipUpdate !== LiveVersion) {
|
||||
fetch('https://polyplus.vercel.app/data/version.json')
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
chrome.storage.local.set({PolyPlus_LiveVersion: data.version}, function () {
|
||||
console.log('Cached live version');
|
||||
});
|
||||
if (data.version > Manifest.version) {
|
||||
chrome.storage.local.set({PolyPlus_OutOfDate: true, PolyPlus_ReleaseNotes: data.releaseNotes}, function () {
|
||||
console.log('Cached update notifier result');
|
||||
});
|
||||
chrome.notifications.create(
|
||||
'',
|
||||
{
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('icon.png'),
|
||||
title: 'New Update Available',
|
||||
message: 'A new update is available for Poly+! (v' + data.version + ')'
|
||||
},
|
||||
function (notificationID) {
|
||||
chrome.notifications.onClicked.addListener(function (id) {
|
||||
if (id === notificationID) {
|
||||
chrome.tabs.create({url: 'https://github.com/IndexingGitHub/PolyPlus/releases', active: true});
|
||||
chrome.notifications.clear(notificationID);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
chrome.contextMenus.removeAll(function () {
|
||||
chrome.contextMenus.create({
|
||||
title: 'Run Update Notifier',
|
||||
id: 'PolyPlus-RunUpdateNotifier',
|
||||
contexts: ['all'],
|
||||
documentUrlPatterns: [
|
||||
'https://polytoria.com/my/settings/polyplus*'
|
||||
]
|
||||
});
|
||||
|
||||
// COPY ASSET ID CONTEXT MENU ITEM REGISTRATION
|
||||
/*
|
||||
const AssetTypes = ["Place", "User", "Item", "Guild"]
|
||||
|
|
@ -328,6 +493,15 @@ chrome.contextMenus.removeAll(function () {
|
|||
'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/**'
|
||||
]
|
||||
});
|
||||
|
||||
// COPY AVATAR HASH CONTEXT MENU ITEM REGISTRATION
|
||||
chrome.contextMenus.create({
|
||||
|
|
@ -344,12 +518,21 @@ chrome.contextMenus.removeAll(function () {
|
|||
// HANDLE CONTEXT MENU ITEMS
|
||||
chrome.contextMenus.onClicked.addListener(async function (info, tab) {
|
||||
if (["CopyPlaceID", "CopyUserID", "CopyItemID", "CopyGuildID"].indexOf(info.menuItemId.split('-')[1]) !== -1) {
|
||||
console.log(info.linkUrl.split('/')[3]);
|
||||
let ID = info.linkUrl.split('/')[4];
|
||||
if (info.linkUrl.split('/')[3] === 'u') {
|
||||
ID = (await (await fetch('https://api.polytoria.com/v1/users/find?username=' + info.linkUrl.split('/')[4])).json()).id;
|
||||
}
|
||||
console.log(ID);
|
||||
chrome.scripting
|
||||
.executeScript({
|
||||
target: {tabId: tab.id},
|
||||
func: CopyAssetID,
|
||||
args: [ID]
|
||||
})
|
||||
.then(() => console.log('Copied ID!'));
|
||||
}
|
||||
|
||||
if (info.menuItemId === 'PolyPlus-CopyThreadID') {
|
||||
let ID = info.linkUrl.split('/')[5];
|
||||
chrome.scripting
|
||||
.executeScript({
|
||||
target: {tabId: tab.id},
|
||||
|
|
|
|||
61
js/create/audio-library.js
Normal file
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});
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
console.log("PolyPlus: Running image.js");
|
||||
/*
|
||||
credit to goldenretriveryt on Polytoria for making the multi-decal uploading feature
|
||||
*/
|
||||
|
||||
(async () => {
|
||||
var Settings = [];
|
||||
|
|
@ -11,8 +13,6 @@ console.log("PolyPlus: Running image.js");
|
|||
|
||||
if (Settings.UploadMultipleDecals === true) {
|
||||
UploadMultipleDecals();
|
||||
} else {
|
||||
console.log("PolyPlus: UploadMultipleDecals is disabled");
|
||||
}
|
||||
|
||||
async function UploadMultipleDecals() {
|
||||
|
|
@ -20,8 +20,10 @@ console.log("PolyPlus: Running image.js");
|
|||
fileInput.setAttribute("multiple", "true");
|
||||
|
||||
const submitBtn = document.querySelector(
|
||||
"#main-content > div:nth-child(4) > div.container.p-0.p-lg-5 > div.row.mx-auto > div.col-lg-10 > div.card.mb-2 > div > form > div.form-group.mb-0 > button"
|
||||
"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;
|
||||
|
|
@ -36,6 +38,10 @@ console.log("PolyPlus: Running image.js");
|
|||
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",
|
||||
|
|
@ -45,7 +51,6 @@ console.log("PolyPlus: Running image.js");
|
|||
}
|
||||
);
|
||||
|
||||
console.log(response.status);
|
||||
if (response.ok) {
|
||||
i++;
|
||||
submitBtn.textContent =
|
||||
|
|
|
|||
264
js/create/place-access.js
Executable file
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.has
|
|||
<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/IndexingGitHub/PolyPlus" class="btn btn-dark btn-sm w-100 mt-2" target="_blank">Open GitHub</a>
|
||||
<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>
|
||||
|
|
@ -75,17 +75,21 @@ if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.has
|
|||
<hr>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header text-primary">RUN TESTS</div>
|
||||
<div class="card-header text-primary">Tools</div>
|
||||
<div class="card-body">
|
||||
<label>Test "IRL Price with Brick Count"</label>
|
||||
<p>will add later</p>
|
||||
<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-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>
|
||||
|
|
@ -234,14 +238,41 @@ if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.has
|
|||
});
|
||||
});
|
||||
|
||||
chrome.storage.sync.getBytesInUse(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_BestFriends', 'PolyPlus_ItemWishlist'], function (bytes) {
|
||||
console.log(bytes)
|
||||
document.getElementById('data-size').innerText = bytes.toLocaleString();
|
||||
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'], function(result) {
|
||||
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 {
|
||||
|
|
@ -254,76 +285,228 @@ if (window.location.pathname.split('/')[3] === 'polyplus' && window.location.has
|
|||
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">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>
|
||||
<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-5" style="padding-left: 0px;">
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h2>Settings</h2>
|
||||
<div style="padding: 10px; background: #171717; font-family: monospace; color: orange; font-size: 0.8rem; border-radius: 10px; position: relative;">
|
||||
${JSON.stringify((result.PolyPlus_Settings || {}), 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((result.PolyPlus_Settings || [])).replaceAll('"', "\'")}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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/IndexingGitHub/PolyPlus" class="btn btn-dark btn-sm w-100 mt-2" target="_blank">Open GitHub</a>
|
||||
<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">
|
||||
<div class="card-body">
|
||||
<h3>Pinned Games (${(result.PolyPlus_PinnedGames || []).length})</h3>
|
||||
<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((result.PolyPlus_PinnedGames || []), null, 2)
|
||||
${JSON.stringify((sync.PolyPlus_Settings || {}), 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((result.PolyPlus_PinnedGames || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h3>Best Friends (${(result.PolyPlus_BestFriends || []).length})</h3>
|
||||
<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((result.PolyPlus_BestFriends || []), null, 2)
|
||||
${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((result.PolyPlus_BestFriends || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||
<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">
|
||||
<div class="card-body">
|
||||
<h3>Item Wishlist (${(result.PolyPlus_ItemWishlist || []).length})</h3>
|
||||
<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((result.PolyPlus_ItemWishlist || []), null, 2)
|
||||
${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', ' ')}
|
||||
<button class="btn btn-warning btn-sm" style="position: absolute; top: 0; right: 0; margin: 10px;" onclick="navigator.clipboard.writeText('${JSON.stringify((result.PolyPlus_ItemWishlist || []))}') .then(() => {alert('copied')}) .catch(() => {});">copy</button>
|
||||
</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();
|
||||
})
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
@ -20,13 +20,21 @@ function ForumMentions() {
|
|||
const Regex = /@([\w.]+)/g;
|
||||
|
||||
for (let text of ForumText) {
|
||||
let FormattedText = text.innerHTML;
|
||||
let match;
|
||||
while ((match = Regex.exec(text.innerText)) !== null) {
|
||||
const Username = match[0].substring(1);
|
||||
FormattedText = FormattedText.replaceAll(match[0], `<a href="/users/@${Username}?ref=${encodeURIComponent(window.location.pathname)}" class="polyplus-mention">${match[0]}</a>`);
|
||||
const TreeWalker = document.createTreeWalker(text, NodeFilter.SHOW_TEXT, null, false);
|
||||
let Node;
|
||||
|
||||
while ((Node = TreeWalker.nextNode())) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +52,6 @@ function ForumUnixTimestamps() {
|
|||
const Distance = new Intl.RelativeTimeFormat({numeric: 'auto', style: 'short'}).format(Math.floor((Timestamp - new Date()) / (60 * 1000)), 'day');
|
||||
const Result = `<code style="color: orange;">${Months[Timestamp.getMonth()]} ${Timestamp.getDate()}, ${Timestamp.getFullYear()} (${['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][Timestamp.getDay() - 1]}) at ${Timestamp.getHours() - 12}:${String(Timestamp.getMinutes()).padStart(2, '0')} (${Distance})</code>`;
|
||||
FormattedText = FormattedText.replaceAll(match[0], Result);
|
||||
console.log(FormattedText);
|
||||
}
|
||||
text.innerHTML = FormattedText;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,142 +0,0 @@
|
|||
const PlaceID = window.location.pathname.split('/')[3];
|
||||
const Form = document.querySelector('form[action="/create/place/update"]');
|
||||
|
||||
var Settings;
|
||||
var PlaceData = null;
|
||||
|
||||
!(async () => {
|
||||
ActivityToggle();
|
||||
//RequestGameProfile()
|
||||
CopyOwnedPlace();
|
||||
})();
|
||||
|
||||
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 ${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', async function () {
|
||||
const Toggle = (await (await fetch(`https://polytoria.com/api/places/${PlaceID}/toggle-active`,{ method: 'POST' })).json())
|
||||
console.log(Toggle)
|
||||
if (Toggle.success) {
|
||||
Status = data.isActive;
|
||||
ActivityBtn.innerText = Status === true ? 'Deactivate' : 'Activate';
|
||||
ActivityBtn.classList = 'btn ' + (Status === true ? 'btn-danger' : 'btn-success');
|
||||
} else {
|
||||
chrome.runtime.sendMessage({ action: "sweetalert2", icon: "error", title: "Error", text: Toggle.message });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 () {
|
||||
console.log('clicked download epic');
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
const PlaceID = window.location.pathname.split('/')[2];
|
||||
const PlaceID = parseInt(window.location.pathname.split('/')[2]);
|
||||
const UserID = JSON.parse(window.localStorage.getItem('p+account_info')).ID;
|
||||
const GameCreator = document.querySelector('#main-content .card-body .col div.text-muted a[href^="/users/"]').getAttribute('href').split('/')[2];
|
||||
|
||||
let Utilities;
|
||||
let PlaceDetails = null;
|
||||
|
||||
var Settings;
|
||||
let TimePlayed;
|
||||
var PinnedGamesData = [];
|
||||
let GamePinned;
|
||||
|
||||
|
|
@ -44,14 +46,15 @@ const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [
|
|||
|
||||
RatingsContainer.children[0].appendChild(PercentageLabel);
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
||||
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames', 'PolyPlus_TimePlayed'], async function (result) {
|
||||
Settings = result.PolyPlus_Settings || {};
|
||||
TimePlayed = result.PolyPlus_TimePlayed || {};
|
||||
|
||||
Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
|
||||
if (Settings.PinnedGamesOn === true) {
|
||||
PinnedGames();
|
||||
PinnedGames(result.PolyPlus_PinnedGames);
|
||||
}
|
||||
|
||||
if (Settings.InlineEditingOn === true && GameCreator === UserID) {
|
||||
|
|
@ -71,6 +74,33 @@ const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [
|
|||
IRLPrice();
|
||||
}
|
||||
|
||||
if (Settings.TimePlayedOn === true) {
|
||||
const TimePlayedNameRow = document.createElement('li');
|
||||
TimePlayedNameRow.innerText = 'Time Played:';
|
||||
|
||||
const TimePlayedValueRow = document.createElement('li')
|
||||
if (TimePlayed[PlaceID]) {
|
||||
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>'
|
||||
} 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>'
|
||||
}
|
||||
|
||||
InfoColumns[0].appendChild(TimePlayedNameRow);
|
||||
InfoColumns[1].appendChild(TimePlayedValueRow);
|
||||
|
||||
if (document.getElementById('btn-play')) {
|
||||
document.getElementById('btn-play').addEventListener('click', function(){
|
||||
chrome.runtime.sendMessage({ action: "start_time_played", placeID: PlaceID, userID: UserID });
|
||||
})
|
||||
|
||||
Array.from(document.querySelectorAll('button[onclick^="joinPlace"]')).forEach(serverJoin => {
|
||||
serverJoin.addEventListener("click", function(){
|
||||
chrome.runtime.sendMessage({ action: "start_time_played", placeID: PlaceID, userID: UserID })
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.ShowPlaceRevenueOn === true) {
|
||||
const NameRow = document.createElement('li');
|
||||
NameRow.innerText = 'Revenue:';
|
||||
|
|
@ -95,107 +125,112 @@ const Gamepasses = Array.from(GamepassesTab.getElementsByClassName('card')) || [
|
|||
});
|
||||
}
|
||||
|
||||
if (AchievementsTab.getElementsByClassName('display-3')[0] === undefined) {
|
||||
if (Settings.ImprovedAchievements && Settings.ImprovedAchievements.Enabled === true && AchievementsTab.getElementsByClassName('display-3')[0] === undefined) {
|
||||
if (Settings.ImprovedAchievements.ProgressBarOn && Settings.ImprovedAchievements.ProgressBarOn === true) {
|
||||
AchievementProgressBar();
|
||||
AchievementEarnedPercentage();
|
||||
}
|
||||
|
||||
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>
|
||||
`;
|
||||
|
||||
async function PinnedGames() {
|
||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
|
||||
PinnedGamesData = 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 (PinnedGamesData.includes(parseInt(PlaceID))) {
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
||||
} else {
|
||||
if (PinnedGamesData.length !== Utilities.Limits.PinnedGames) {
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
|
||||
} else {
|
||||
PinBtn.setAttribute('disabled', true);
|
||||
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
PinBtn.addEventListener('click', function () {
|
||||
PinBtn.setAttribute('disabled', 'true');
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
|
||||
PinnedGamesData = result.PolyPlus_PinnedGames || [];
|
||||
/*
|
||||
const Index = PinnedGames.indexOf(parseInt(PlaceID))
|
||||
if (Index !== -1) {
|
||||
//delete PinnedGames[PlaceID]
|
||||
PinnedGames.splice(Index, 1)
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin'
|
||||
PinButton.children[0].classList = 'fa-regular fa-star';
|
||||
} else {
|
||||
//PinnedGames[PlaceID] = {lastVisited: new Date()}
|
||||
PinnedGames.push(parseInt(PlaceID))
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
||||
}
|
||||
*/
|
||||
const Index = PinnedGamesData.indexOf(parseInt(PlaceID));
|
||||
if (Index !== -1) {
|
||||
PinnedGamesData.splice(Index, 1);
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
|
||||
} else {
|
||||
PinnedGamesData.push(parseInt(PlaceID));
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
||||
// Pinned
|
||||
PinButton.children[0].classList = 'fa-duotone fa-star';
|
||||
}
|
||||
};
|
||||
|
||||
chrome.storage.sync.set({PolyPlus_PinnedGames: PinnedGamesData, arrayOrder: true}, function () {
|
||||
setTimeout(function () {
|
||||
PinBtn.removeAttribute('disabled');
|
||||
console.log(PinnedGamesData);
|
||||
}, 1250);
|
||||
});
|
||||
});
|
||||
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');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementsByClassName('card-header')[2].appendChild(PinBtn);
|
||||
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');
|
||||
}
|
||||
});
|
||||
|
||||
chrome.storage.onChanged.addListener(function (changes, namespace) {
|
||||
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) {
|
||||
chrome.storage.sync.get(['PolyPlus_PinnedGames'], function (result) {
|
||||
PinnedGamesData = result.PolyPlus_PinnedGames || [];
|
||||
|
||||
/*
|
||||
if (PinnedGamesData[PlaceID]) {
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin'
|
||||
} else {
|
||||
if (PinnedGamesData.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)'
|
||||
placeIDs = changes.PolyPlus_PinnedGames.newValue;
|
||||
UpdatePinButtonState();
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (PinnedGamesData.includes(parseInt(PlaceID))) {
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Un-pin';
|
||||
} else {
|
||||
if (PinnedGamesData.length !== Utilities.Limits.PinnedGames) {
|
||||
PinBtn.removeAttribute('disabled');
|
||||
PinBtn.innerHTML = '<i class="fa-duotone fa-star"></i> Pin';
|
||||
} else {
|
||||
PinBtn.setAttribute('disabled', true);
|
||||
PinBtn.innerHTML = `<i class="fa-duotone fa-star"></i> Pin (max ${Utilities.Limits.PinnedGames}/${Utilities.Limits.PinnedGames})`;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -383,8 +418,9 @@ async function IRLPrice() {
|
|||
async function PlaceRevenue() {
|
||||
const BricksPerView = 5;
|
||||
|
||||
let PlaceDetails = await fetch('https://api.polytoria.com/v1/places/' + PlaceID);
|
||||
PlaceDetails = await PlaceDetails.json();
|
||||
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();
|
||||
|
|
@ -426,7 +462,7 @@ async function PlaceRevenue() {
|
|||
const ResultText = document.createElement('li');
|
||||
ResultText.classList = 'fw-normal text-success';
|
||||
ResultText.style.letterSpacing = '0px';
|
||||
ResultText.innerHTML = `<i class="pi pi-brick mx-1"></i> ~` + Revenue.toLocaleString() + ' <i class="fa fa-question"></i>';
|
||||
ResultText.innerHTML = `<i class="pi pi-brick mx-1"></i> ~` + Revenue.toLocaleString();
|
||||
|
||||
CalculateRevenueButton.remove();
|
||||
InfoColumns[1].appendChild(ResultText);
|
||||
|
|
@ -468,31 +504,12 @@ function AchievementProgressBar() {
|
|||
AchievementsTab.prepend(ProgressBar);
|
||||
}
|
||||
|
||||
function AchievementEarnedPercentage() {
|
||||
fetch('https://api.polytoria.com/v1/places/' + PlaceID)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
const UserCount = data.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) + ')';
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
async function AchievementEarnedPercentage() {
|
||||
if (PlaceDetails === null) {
|
||||
PlaceDetails = (await (await fetch('https://api.polytoria.com/v1/places/' + PlaceID)).json());
|
||||
}
|
||||
|
||||
function GetAchievementDifficulty(percent) {
|
||||
const GetAchievementDifficulty = function(percent) {
|
||||
if (percent >= 90 && percent <= 100) {
|
||||
return 'Freebie';
|
||||
} else if (percent >= 80 && percent <= 89.9) {
|
||||
|
|
@ -513,3 +530,70 @@ function GetAchievementDifficulty(percent) {
|
|||
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,33 +0,0 @@
|
|||
/*
|
||||
THIS FILE DOES NOT RUN
|
||||
IT WAS ADDED WHILE I CONSIDER WHETHER OR NOT TO ADD PINNED GAMES TO THE MAIN PLACES PAGE
|
||||
*/
|
||||
|
||||
let Settings;
|
||||
let PinnedGamesData;
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings', 'PolyPlus_PinnedGames'], function (result) {
|
||||
Settings = result.PolyPlus_Settings || {};
|
||||
PinnedGamesData = result.PolyPlus_PinnedGames || [];
|
||||
|
||||
if (Settings.PinnedGamesOn === true) {
|
||||
}
|
||||
});
|
||||
|
||||
function PinnedGames() {
|
||||
for (let game of PinnedGamesData) {
|
||||
fetch('https://api.polytoria.com/v1/places/' + game)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
// epic
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
37
js/site-redirects.js
Normal file
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)
|
||||
}
|
||||
133
js/sitewide.js
133
js/sitewide.js
|
|
@ -1,26 +1,19 @@
|
|||
console.log('start of script')
|
||||
|
||||
var Settings;
|
||||
let Theme = ``;
|
||||
|
||||
(async () => {
|
||||
console.log('start of async')
|
||||
let Utilities = await import(chrome.runtime.getURL('resources/utils.js'));
|
||||
Utilities = Utilities.default;
|
||||
console.log('imported utils')
|
||||
|
||||
chrome.storage.sync.get(['PolyPlus_Settings'], function (result) {
|
||||
console.log("fetched settings: ", 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() {
|
||||
console.log("fired dom load")
|
||||
if (document.getElementsByClassName('card-header')[0] && document.getElementsByClassName('card-header')[0].innerText === ' Page not found') {
|
||||
return;
|
||||
}
|
||||
console.log("passed error check")
|
||||
|
||||
Utilities.InjectResource('getUserDetails');
|
||||
document.body.setAttribute('data-URL', window.location.pathname);
|
||||
|
|
@ -45,28 +38,6 @@ let Theme = ``;
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (document.readyState === 'complete') {
|
||||
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") {
|
||||
console.log("Reloading Poly+...");
|
||||
chrome.runtime.sendMessage({ action: "reload" });
|
||||
window.location.reload();
|
||||
} else if (!combination.startsWith(currentCombination)) {
|
||||
currentCombination = "";
|
||||
}
|
||||
});
|
||||
|
||||
if (Settings.HideUserAds && Settings.HideUserAds.Enabled === true) {
|
||||
if (Settings.HideUserAds.Banners && Settings.HideUserAds.Banners === true) {
|
||||
|
|
@ -107,6 +78,110 @@ let Theme = ``;
|
|||
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 = "";
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
const ItemID = window.location.pathname.split('/')[2];
|
||||
if (window.location.pathname.slice(-6) == "/asset") {
|
||||
window.location.href = "https://api.polytoria.com/v1/assets/serve-mesh/" + ItemID
|
||||
}
|
||||
let ItemModeler = null;
|
||||
const ItemType = document.querySelector('.row .badge').innerHTML;
|
||||
console.log(ItemType);
|
||||
|
||||
var Settings;
|
||||
var ItemWishlist;
|
||||
|
|
@ -19,11 +22,8 @@ var Utilities;
|
|||
chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
||||
Settings = result.PolyPlus_Settings || {};
|
||||
|
||||
PurchaseBtn = document.querySelector('.btn[onclick^="buy"]');
|
||||
if (PurchaseBtn === null) {
|
||||
PurchaseBtn = document.querySelector('.btn#purchase-button');
|
||||
}
|
||||
ItemOwned = PurchaseBtn.innerText === ' Item owned' || document.querySelector('.btn[onclick="sellItem()"]') !== null;
|
||||
PurchaseBtn = document.querySelector('.col:has(h1) .justify-content-lg-end .d-flex .flex-grow-1:nth-child(2) :nth-child(1)')
|
||||
ItemOwned = PurchaseBtn.innerText === ' Item owned' || PurchaseBtn.innerText === ' You earned this achievement' || document.querySelector('.btn[onclick="sellItem()"]') !== null;
|
||||
|
||||
if (PurchaseBtn.getAttribute('data-seller-name')) {
|
||||
PurchaseBtn.setAttribute('data-bs-toggle', 'tooltip');
|
||||
|
|
@ -55,13 +55,45 @@ var Utilities;
|
|||
if (Settings.HoardersList && Settings.HoardersList.Enabled === true) {
|
||||
HoardersList(parseInt(Settings.HoardersList.MinCopies), Settings.HoardersList.AvatarsEnabled);
|
||||
}
|
||||
} else if (Settings.ItemOwnerCheckOn === true && document.getElementById('timer') && /\d/.test(document.getElementById('timer').innerText)) {
|
||||
|
||||
if (
|
||||
Settings.ValueListInfo &&
|
||||
Settings.ValueListInfo.Enabled == true &&
|
||||
Settings.ValueListInfo.ItemValuation == true
|
||||
) {
|
||||
ValueListData()
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.ItemOwnerCheckOn === true && ((document.getElementById('timer') !== null && /\d/.test(document.getElementById('timer').innerText) || document.getElementById('resellers') !== null))) {
|
||||
CheckOwner();
|
||||
}
|
||||
|
||||
if (Settings.ItemWishlistOn === true) {
|
||||
HandleItemWishlist();
|
||||
}
|
||||
|
||||
if (Settings.AssetDesignerCreditOn === true) {
|
||||
chrome.storage.local.get(['PolyPlus_AssetDesigners'], async function(result){
|
||||
let AssetDesignerData = result['PolyPlus_AssetDesigners'];
|
||||
|
||||
// cache for 5 minutes
|
||||
if (AssetDesignerData === undefined || (new Date().getTime() - AssetDesignerData.requested > 300000)) {
|
||||
AssetDesignerData = await ((await fetch('https://polyplus.vercel.app/data/itemModelers.json')).json());
|
||||
|
||||
chrome.storage.local.set({['PolyPlus_AssetDesigners']: {
|
||||
data: AssetDesignerData,
|
||||
requested: new Date().getTime()
|
||||
}}, function(){});
|
||||
} else {
|
||||
AssetDesignerData = AssetDesignerData.data
|
||||
}
|
||||
|
||||
if (AssetDesignerData[ItemID]) {
|
||||
AssetDesignerInfo(AssetDesignerData)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
|
|
@ -214,7 +246,7 @@ function TryOnItems() {
|
|||
const ItemThumbnail = document.getElementsByClassName('store-thumbnail')[0];
|
||||
//const IFrame = document.getElementsByClassName('store-thumbnail-3d')[0]
|
||||
const TryIFrame = document.createElement('iframe');
|
||||
TryIFrame.style = 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px;';
|
||||
TryIFrame.style = 'width: 100%; height: auto; aspect-ratio: 1; border-radius: 20px; background: #1e1e1e;';
|
||||
|
||||
const TryOnBtn = document.createElement('button');
|
||||
TryOnBtn.classList = 'btn btn-warning';
|
||||
|
|
@ -235,22 +267,18 @@ function TryOnItems() {
|
|||
})
|
||||
.then((data) => {
|
||||
data.assets.forEach((item) => {
|
||||
switch (item.type) {
|
||||
case 'hat':
|
||||
if (item.type !== AssetType.toLowerCase()) {
|
||||
if (item.type === 'hat') {
|
||||
Avatar.items[Avatar.items.length] = item.path || '';
|
||||
break;
|
||||
case 'face':
|
||||
} else if (item.type === 'face') {
|
||||
Avatar.face = item.path || '';
|
||||
break;
|
||||
case 'tool':
|
||||
} else if (item.type === 'tool') {
|
||||
Avatar.tool = item.path || '';
|
||||
break;
|
||||
case 'shirt':
|
||||
} else if (item.type === 'shirt') {
|
||||
Avatar.shirt = item.path || '';
|
||||
break;
|
||||
case 'pants':
|
||||
} else if (item.type === 'pants') {
|
||||
Avatar.pants = item.path || '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -270,13 +298,12 @@ function TryOnItems() {
|
|||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
if (ItemType === 'tool') {
|
||||
if (AssetType === 'Tool') {
|
||||
Avatar.tool = data.url;
|
||||
} else {
|
||||
Avatar.items.push(data.url);
|
||||
}
|
||||
|
||||
console.log(Avatar);
|
||||
TryIFrame.src = 'https://polytoria.com/ptstatic/itemview/#' + btoa(encodeURIComponent(JSON.stringify(Avatar)));
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
@ -357,7 +384,7 @@ async function HoardersList(min, avatars) {
|
|||
TabContent.classList = 'd-none';
|
||||
TabContent.innerHTML = `
|
||||
<small class="d-block text-center text-muted" style="font-size: 0.8rem;">
|
||||
loading... (this may take a few seconds)
|
||||
Loading... (this may take a few seconds)
|
||||
</small>
|
||||
<lottie-player id="avatar-loading" src="https://c0.ptacdn.com/static/images/lottie/poly-brick-loading.2b51aa85.json" background="transparent" speed="1" style="width: 20%;height: auto;margin: -16px auto 50px;margin-top: 0px;" loop="" autoplay=""></lottie-player>
|
||||
`;
|
||||
|
|
@ -428,11 +455,9 @@ async function HoardersList(min, avatars) {
|
|||
try {
|
||||
AvatarsFetched++
|
||||
const Avatar = (await (await fetch('https://api.polytoria.com/v1/users/' + hoarder.user.id)).json());
|
||||
console.log(hoarder.user.username, Avatar)
|
||||
hoarder.user.avatar = Avatar.thumbnail.icon;
|
||||
} catch(error) {
|
||||
hoarder.user.avatar = ''
|
||||
console.log(hoarder.user.username + ` (${hoarder.user.id}) - avatar failed`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -596,7 +621,6 @@ async function HoardersList(min, avatars) {
|
|||
});
|
||||
|
||||
const UpdateHoardersList = function () {
|
||||
console.log(Hoarders, AmountOfHoarders, Groups);
|
||||
Current.innerText = Page + 1;
|
||||
|
||||
if (Groups[Page] !== undefined) {
|
||||
|
|
@ -723,7 +747,7 @@ function CheckOwner() {
|
|||
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' owns #' + Owns.inventory.serial + ' of "' + document.getElementsByTagName('h1')[0].innerText + '".';
|
||||
} else {
|
||||
ResultText.classList = 'text-danger';
|
||||
ResultText.innerHTML = '<i class="fa-duotone fa-circle-check mr-1"></i> ' + Username + ' does not own "' + document.getElementsByTagName('h1')[0].innerText + '".';
|
||||
ResultText.innerHTML = '<i class="fa-duotone fa-circle-exclamation mr-1"></i> ' + Username + ' does not own "' + document.getElementsByTagName('h1')[0].innerText + '".';
|
||||
}
|
||||
} else {
|
||||
ResultText.classList = 'text-warning';
|
||||
|
|
@ -731,3 +755,202 @@ function CheckOwner() {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function ValueListDataNew() {
|
||||
let Tabs = document.getElementById('store-tabs');
|
||||
|
||||
const ValueSection = document.createElement('div')
|
||||
ValueSection.classList = 'mb-3'
|
||||
ValueSection.innerHTML = `
|
||||
<h6 class="section-title mt-3 mt-lg-0 mb-3 px-2">
|
||||
Valuation <a href="https://polytoria.trade/" target="_blank">(based off LOVE)</a>
|
||||
</h6>
|
||||
<div class="card" id="p+valuation_card">
|
||||
<div class="card-body">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
Tabs.parentElement.insertBefore(ValueSection, Tabs)
|
||||
|
||||
const ValueCard = document.getElementById('p+valuation_card').children[0]
|
||||
|
||||
const TagColors = {
|
||||
"Projected": "warning",
|
||||
"Hoarded": "success",
|
||||
"Rare": "primary",
|
||||
"Freaky": "danger"
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
await chrome.runtime.sendMessage({
|
||||
action: "item_valuation",
|
||||
itemID: ItemID
|
||||
});
|
||||
}
|
||||
|
||||
async function ValueListData() {
|
||||
let Tabs = document.getElementById('store-tabs');
|
||||
|
||||
const ValueSection = document.createElement('div')
|
||||
ValueSection.classList = 'mb-3'
|
||||
ValueSection.innerHTML = `
|
||||
<h6 class="section-title mt-3 mt-lg-0 mb-3 px-2">
|
||||
Valuation <a href="https://docs.google.com/document/d/1W7JN74MU-9Dbd-9xNnjxE18hQVBPXWuwjK5DGSnuQR4/" target="_blank">(based off LOVE)</a>
|
||||
</h6>
|
||||
<div class="card" id="p+valuation_card">
|
||||
<div class="card-body">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
Tabs.parentElement.insertBefore(ValueSection, Tabs)
|
||||
|
||||
const ValueCard = document.getElementById('p+valuation_card').children[0]
|
||||
|
||||
const ColumnLabels = [
|
||||
"name",
|
||||
"short",
|
||||
"value",
|
||||
"type",
|
||||
"trend",
|
||||
"demand",
|
||||
"tags"
|
||||
]
|
||||
|
||||
const TagColors = {
|
||||
"Projected": "warning",
|
||||
"Hoarded": "success",
|
||||
"Rare": "primary",
|
||||
"Freaky": "danger"
|
||||
}
|
||||
|
||||
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')
|
||||
|
||||
/*
|
||||
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 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 ValueDetails = ExtractTableJSON(ValueListDocument.getElementsByTagName('table')[0]).filter((x) => x.id === ItemID)[0]
|
||||
|
||||
if (ValueDetails !== 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">
|
||||
${ValueDetails.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">
|
||||
${ValueDetails.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">
|
||||
${ValueDetails.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">
|
||||
${ValueDetails.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.
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
async function AssetDesignerInfo(data) {
|
||||
let QuickStats = document.querySelectorAll('.row:has(h3, h6, [data-bs-tooltip])')[2];
|
||||
|
||||
const CreatorStat = document.createElement('div')
|
||||
CreatorStat.classList = 'col text-center'
|
||||
CreatorStat.innerHTML = `
|
||||
<h6>Asset Designer</h6>
|
||||
<h3 class="small">
|
||||
<a href="/u/${data[ItemID]}" style="background-clip:text;-webkit-background-clip:text;color:transparent;background-image: linear-gradient(90deg, #1ad05b, #68f);-webkit-text-fill-color: transparent;">${data[ItemID]}</a>
|
||||
</h3>
|
||||
`
|
||||
QuickStats.appendChild(CreatorStat)
|
||||
}
|
||||
|
|
@ -27,10 +27,8 @@ chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
|||
|
||||
if (Settings.StoreOwnTagOn === true) {
|
||||
chrome.storage.local.get('PolyPlus_InventoryCache', async function(result){
|
||||
console.log(result)
|
||||
if (result.PolyPlus_InventoryCache !== undefined && (new Date().getTime() - result.PolyPlus_InventoryCache[1] < 5000)) {
|
||||
console.log('not undefined')
|
||||
Inventory = result.PolyPlus_InventoryCache[0]
|
||||
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);
|
||||
});
|
||||
|
|
@ -41,8 +39,7 @@ chrome.storage.sync.get(['PolyPlus_Settings'], async function (result) {
|
|||
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];
|
||||
console.log(Inventory);
|
||||
chrome.storage.local.set({'PolyPlus_InventoryCache': [Inventory, new Date().getTime()]}, function(){})
|
||||
chrome.storage.local.set({'PolyPlus_InventoryCache': {data: Inventory, requested: new Date().getTime()}}, function(){})
|
||||
Array.from(ItemGrid.children).forEach((element) => {
|
||||
LoadOwnedTags(element);
|
||||
});
|
||||
|
|
@ -103,8 +100,13 @@ async function LoadIRLPrices(element) {
|
|||
}
|
||||
}
|
||||
|
||||
function LoadOwnedTags(element) {
|
||||
let Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]));
|
||||
function LoadOwnedTags(element, id) {
|
||||
let Item;
|
||||
if (id !== undefined) {
|
||||
Item = CheckInventory(parseInt(id))
|
||||
} else {
|
||||
Item = CheckInventory(parseInt(element.querySelector('[href^="/store/"]').getAttribute('href').split('/')[2]));
|
||||
}
|
||||
if (Item !== null) {
|
||||
const Tag = document.createElement('span');
|
||||
Tag.classList = `badge ${Item.asset.isLimited === false ? 'bg-primary' : 'bg-warning'} polyplus-own-tag`;
|
||||
|
|
@ -177,16 +179,21 @@ function EventItems() {
|
|||
<h6 class="dash-ctitle2">${x.date}</h6>
|
||||
<h5 class="dash-ctitle">${x.name}</h5>
|
||||
</div>
|
||||
${x.link !== undefined ? `
|
||||
${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">
|
||||
|
|
@ -245,6 +252,12 @@ function EventItems() {
|
|||
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');
|
||||
|
|
@ -345,6 +358,12 @@ function EventItems() {
|
|||
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]);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
96
js/the-great-divide.js
Normal file
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]
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
"manifest_version": 3,
|
||||
"author": "Index",
|
||||
"name": "Poly+",
|
||||
"version": "1.21",
|
||||
"version_name": "Pre-Release Build (v1.2.1)",
|
||||
"version": "1.3",
|
||||
"version_name": "Release Build (v1.3)",
|
||||
"description": "Power-up your Polytoria experience with Poly+! Created by Index.",
|
||||
"homepage_url": "https://polyplus.vercel.app/",
|
||||
"permissions": ["storage", "contextMenus", "scripting", "alarms", "notifications"],
|
||||
|
|
@ -33,8 +33,8 @@
|
|||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/create/place/**"],
|
||||
"js": ["/js/places/place-edit.js"]
|
||||
"matches": ["https://polytoria.com/create/place/**/access"],
|
||||
"js": ["/js/create/place-access.js"]
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/store/**"],
|
||||
"matches": ["https://polytoria.com/store/**", "https://polytoria.com/store/*/asset"],
|
||||
"js": ["/js/store/item-view.js"]
|
||||
},
|
||||
|
||||
|
|
@ -100,7 +100,7 @@
|
|||
|
||||
{
|
||||
"matches": ["https://polytoria.com/my/avatar*"],
|
||||
"js": ["/js/account/avatar-sandbox2.js"]
|
||||
"js": ["/js/account/avatar-sandbox.js"]
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -119,8 +119,23 @@
|
|||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/places/**", "https://polytoria.com/u/**"],
|
||||
"js": ["the-great-divide.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/*"],
|
||||
"js": ["/js/site-redirects.js"]
|
||||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/library"],
|
||||
"js": ["/js/create/audio-library.js"]
|
||||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/u/**"],
|
||||
"js": ["/js/the-great-divide.js"]
|
||||
},
|
||||
|
||||
{
|
||||
"matches": ["https://polytoria.com/trade/view/**"],
|
||||
"js": ["/js/account/trade-valuation.js"]
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
|
|
@ -147,7 +162,8 @@
|
|||
"32": "/images/icon.png",
|
||||
"48": "/images/icon.png",
|
||||
"128": "/images/icon.png"
|
||||
}
|
||||
},
|
||||
"default_popup": "/popup.html"
|
||||
},
|
||||
"icons": {
|
||||
"16": "/images/icon.png",
|
||||
|
|
|
|||
13
popup.html
13
popup.html
|
|
@ -11,8 +11,19 @@
|
|||
<!-- RESOURCES -->
|
||||
<link rel="stylesheet" href="css/polytoria.css" />
|
||||
</head>
|
||||
<body style="width: 245px; /*height: 200px;*/">
|
||||
<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">
|
||||
|
|
|
|||
2
popup.js
2
popup.js
|
|
@ -2,6 +2,8 @@
|
|||
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(){
|
||||
|
|
|
|||
|
|
@ -34,17 +34,147 @@
|
|||
#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>
|
||||
<div class="alert bg-danger" role="banner">
|
||||
The Avatar Sandbox is currently being rewritten to have better caching and better, more reliable code. It should be included in v1.2.3
|
||||
<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">
|
||||
<h6 class="card-header">
|
||||
<i class="fad fa-user-crown"></i>
|
||||
Poly+ Avatar Sandbox
|
||||
</h6>
|
||||
<div class="card-body">
|
||||
<iframe id="viewFrame" style="width: 100%; height: 314px; border-radius: 0.65rem;"></iframe>
|
||||
<div id="options">
|
||||
|
|
@ -60,10 +190,6 @@
|
|||
<i class="fa-duotone fa-download"></i>
|
||||
</button>
|
||||
|
||||
<button id="openNewTab" aria-label="View in a new tab!" style="display: block;" data-bs-toggle="tooltip" data-bs-title="New Tab" data-bs-placement="right">
|
||||
<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()" data-bs-toggle="tooltip" data-bs-title="Full Screen" data-bs-placement="right">
|
||||
<i class="fa-duotone fa-minimize"></i>
|
||||
</button>
|
||||
|
|
@ -89,23 +215,33 @@
|
|||
</div>
|
||||
</div>
|
||||
<hr class="mt-2 mb-3">
|
||||
<select class="form-select mb-2" id="load-asset-type">
|
||||
<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 mb-3">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control bg-dark" placeholder="Asset ID.." />
|
||||
<button class="btn btn-primary" id="load-asset">Load Asset</button>
|
||||
<button class="btn btn-primary" id="load-asset">Wear</button>
|
||||
</div>
|
||||
<hr class="mt-2 mb-3">
|
||||
<div class="card mcard mb-3">
|
||||
<h6 class="card-header">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mcard mb-1">
|
||||
<h6 class="card-header text-center">
|
||||
<i class="fad fa-palette"></i>
|
||||
Body Colors
|
||||
</h6>
|
||||
|
|
@ -126,43 +262,95 @@
|
|||
</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 nav-justified mb-3" id="tabs">
|
||||
<li class="nav-item">
|
||||
<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-cowboy me-1"></i>
|
||||
Hats
|
||||
<i class="fas fa-hat-wizard me-1"></i>
|
||||
<span class="pilltitle">Accessories</span>
|
||||
</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">
|
||||
<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>
|
||||
Shirts
|
||||
<span class="pilltitle">Shirts</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<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>
|
||||
Pants
|
||||
<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 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 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">
|
||||
|
|
@ -188,13 +376,8 @@
|
|||
</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: 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="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>
|
||||
<script>
|
||||
console.log('YPOFWPJGUWRHGUWHPOH')
|
||||
var tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
var list = [...tooltips].map((tool) => new bootstrap.Tooltip(tool));
|
||||
</script>
|
||||
|
|
@ -1,2 +1,5 @@
|
|||
var tooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||||
var list = [...tooltips].map((tool) => new bootstrap.Tooltip(tool));
|
||||
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));
|
||||
|
|
@ -108,7 +108,29 @@ export default {
|
|||
UserStatsOn: true,
|
||||
LeaderboardsOn: true
|
||||
},
|
||||
CollectibleInventoryCatOn: 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,
|
||||
|
|
|
|||
508
settings.html
508
settings.html
|
|
@ -288,54 +288,14 @@
|
|||
>
|
||||
Poly+ Settings
|
||||
</h1>
|
||||
<div class="card card-body limited-time setting-container mb-3" id="greatdivide-server-unbalance" style="background-image: linear-gradient(rgba(0.8, 0.8, 0.8, 0.8), rgba(0.8, 0.8, 0.8, 0.8)), url(/images/greatdivide.png); background-size: cover; background-position: center;">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<span class="indicator"> </span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="title">
|
||||
The Great Divide
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="TheGreatDivide">Toggle</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="desc">Reinforcements to aid in your quest to bring home the victory to your team, and bring honor to your peers.</span>
|
||||
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="server-unbalanced-greatdivide" data-setting="UnbalancedIndicatorOn" data-parent="TheGreatDivide" />
|
||||
<label class="form-check-label" for="server-unbalanced-greatdivide">"Potentially Unbalanced" indicator in server list </label>
|
||||
</span>
|
||||
<!--
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="mvp-user-greatdivide" data-setting="MVPUserIndicatorOn" data-parent="TheGreatDivide" />
|
||||
<label class="form-check-label" for="mvp-user-greatdivide"> "MVP" User indicator in server list (not implemented yet)</label>
|
||||
</span>
|
||||
-->
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="user-statistics-greatdivide" data-setting="UserStatsOn" data-parent="TheGreatDivide" />
|
||||
<label class="form-check-label" for="user-statistics-greatdivide">User Statistics tab on profiles</label>
|
||||
</span>
|
||||
<!--
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="leaderboards-greatdivide" data-setting="LeaderboardsOn" data-parent="TheGreatDivide" />
|
||||
<label class="form-check-label" for="leaderboards-greatdivide"> Related ranking leaderboards (not implemented yet)</label>
|
||||
</span>
|
||||
-->
|
||||
|
||||
<small class="text-muted mt-1" style="font-size: 0.7rem;">
|
||||
* some features use <a href="https://polytoria.com/u/dargy" target="_blank">@dargy</a>'s public API! thank you!
|
||||
</small>
|
||||
<small class="limited-time-tag mt-1">
|
||||
* available until July 14th
|
||||
</small>
|
||||
</div>
|
||||
<div class="setting-container" id="pinned-games">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Pinned Games
|
||||
<button class="btn btn-sm toggle-btn" data-setting="PinnedGamesOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="PinnedGamesOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Pin your favorite places to the top of the homepage! (limit: <span id="PinnedGames-limit"></span> places)</span>
|
||||
</div>
|
||||
|
|
@ -343,39 +303,51 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Forum Mentions
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ForumMentsOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ForumMentsOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Get a quick link to the popular person everyone is talking about's profile!</span>
|
||||
<br />
|
||||
<span class="warning">* Forum Mentions do not notify the user or show up as a notification on their account.</span>
|
||||
<span class="desc">
|
||||
Get a quick link to the popular person everyone is talking about's profile!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Forum Mentions do not notify the user or show up as a notification on their account.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="improved-friend-lists">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Improved Friend Lists
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ImprovedFrListsOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ImprovedFrListsOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Accept or decline all friend requests with the click of a button or multi-remove existing friends!
|
||||
<br />
|
||||
<span class="warning">* You can only remove up to <span id="ImprovedFrLists-limit"></span> friends at once.</span>
|
||||
</span>
|
||||
<span class="warning">
|
||||
* You can only remove up to <span id="ImprovedFrLists-limit"></span> friends at once.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="irl-price-with-brick-count">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show IRL price with Brick Count
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="IRLPriceWithCurrency">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="IRLPriceWithCurrency">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc mb-4">
|
||||
<span class="desc">
|
||||
See the real life currency value along with Bricks across the site!
|
||||
<br />
|
||||
<span class="warning">* Currencies were calculated on <span id="IRLPriceWithCurrency-Date">[DATE]</span>.</span>
|
||||
<br />
|
||||
<span class="warning">* Currencies other than USD are purely approximations.</span>
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Currencies were calculated on <span id="IRLPriceWithCurrency-Date">[DATE]</span>.
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Currencies other than USD are purely approximations.
|
||||
</span>
|
||||
<select id="IRLPriceWithCurrencyCurrency" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Currency" data-parent="IRLPriceWithCurrency">
|
||||
<option value="USD" selected>United States Dollar (USD)</option>
|
||||
|
|
@ -403,8 +375,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Hide Notification Badges
|
||||
<button class="btn btn-sm toggle-btn" data-setting="HideNotifBadgesOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="HideNotifBadgesOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Hide the annoying red circles on the sidebar!</span>
|
||||
</div>
|
||||
|
|
@ -412,18 +386,27 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show "OWNED" Tag on Store Main Page
|
||||
<button class="btn btn-sm toggle-btn" data-setting="StoreOwnTagOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="StoreOwnTagOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Quickly see if you own the item at a glance with a little tag in the top left corner of item cards on the main store page! (if the star is blue, then the item is not a collectible - however if the star is yellow/orange then the item is a collectible and you can hover on it to see your serial)</span>
|
||||
<span class="desc">
|
||||
Quickly see if you own the item at a glance with a little tag in the top left corner of item cards on the main store page!
|
||||
</span>
|
||||
<span class="note">
|
||||
* If the star is yellow/orange, that means the item is a collectible and hovering on the star will show your serial.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="theme-creator">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Theme Creator
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ThemeCreator">Toggle</button>
|
||||
<button id="ThemeCreator-Options" class="btn btn-primary btn-sm" data-modal="ThemeCreator">Options</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button id="ThemeCreator-Options" class="btn btn-primary btn-sm options-btn" data-modal="ThemeCreator">Options</button>
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ThemeCreator">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Unleash your creativity and customize the Polytoria website to your liking! (this feature is still in development)</span>
|
||||
</div>
|
||||
|
|
@ -431,19 +414,26 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
More Search Filters
|
||||
<button class="btn btn-sm toggle-btn" data-setting="MoreSearchFiltersOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="MoreSearchFiltersOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Easily find what you're looking for with more search filters side-wide! (this does not affect the main site search on the navbar)</span>
|
||||
<br />
|
||||
<span class="warning">* This currently only has a "Creator" username filter on the forum search page, more search filters are yet to come.</span>
|
||||
<span class="desc">
|
||||
Easily find what you're looking for with more search filters side-wide! (this does not affect the main site search on the navbar)
|
||||
</span>
|
||||
<span class="warning">
|
||||
* This currently only has a "Creator" username filter on the forum search page, more search filters are yet to come.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="apply-membership-theme">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Apply Membership Theme for <b>Free</b>
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ApplyMembershipTheme">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ApplyMembershipTheme">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Ever want the fancy membership themes for completely <b>free</b>? Well now you can get apply them site-wide!</span>
|
||||
<select id="ApplyMembershipThemeTheme" class="form-select form-select-sm mb-2" style="width:350px;" data-setting="Theme" data-parent="ApplyMembershipTheme">
|
||||
|
|
@ -455,8 +445,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Multi-Cancel Outbound Trades
|
||||
<button class="btn btn-sm toggle-btn" data-setting="MultiCancelOutTradesOns">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="MultiCancelOutTradesOns">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quickly cancel several out-bound trades (trades that you have sent) all at once
|
||||
|
|
@ -468,9 +460,11 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Modify Navbar
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ModifyNavOn">Toggle</button>
|
||||
<button id="ModifyNav-Options" class="btn btn-primary btn-sm" data-modal="ModifyNav">Options</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button id="ModifyNav-Options" class="btn btn-primary btn-sm options-btn" data-modal="ModifyNav">Options</button>
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ModifyNavOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc"> Customize the navbar to your liking! </span>
|
||||
</div>
|
||||
|
|
@ -478,8 +472,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Item Wishlist
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ItemWishlistOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ItemWishlistOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc"> Wishlist that item that you REALLY want! </span>
|
||||
</div>
|
||||
|
|
@ -487,8 +483,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Try-On Items
|
||||
<button class="btn btn-sm toggle-btn" data-setting="TryOnItemsOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="TryOnItemsOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">See how that new item looks on your avatar before spending your bricks!</span>
|
||||
</div>
|
||||
|
|
@ -496,8 +494,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show Outfit Cost on Profiles
|
||||
<button class="btn btn-sm toggle-btn" data-setting="OutfitCostOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="OutfitCostOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Quickly see how many bricks a user spent on their avatar!</span>
|
||||
</div>
|
||||
|
|
@ -505,21 +505,26 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show Approximate Place Revenue
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ShowPlaceRevenueOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ShowPlaceRevenueOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Quickly see how many bricks a user has gained from one of their places!</span>
|
||||
<br />
|
||||
<span class="warning"
|
||||
>* Gamepass revenue is calculated assuming the price hasn't changed and all users that bought the gamepass, bought it at the same price that it is at the time of calculating.</span
|
||||
>
|
||||
<span class="desc">
|
||||
Quickly see how many bricks a user has gained from one of their places!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Gamepass revenue is calculated assuming the price hasn't changed and all users that bought the gamepass, bought it at the same price that it is at the time of calculating.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="item-replace-sales">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show "Owners" instead of "Sales"
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ReplaceItemSalesOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ReplaceItemSalesOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Replace the "Sales" statistic with the "Owners" statistic if the item has 0 sales (most likely meaning it is an item awarded by staff).</span>
|
||||
</div>
|
||||
|
|
@ -527,16 +532,23 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Collectibles' Hoarders List
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HoardersList">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HoardersList">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">List all the users that have more than 1 copy of a collectible!</span>
|
||||
<span class="note mb-3">
|
||||
* The hoarders list is limited to <span id="HoardersList-pageLimit"></span> pages to reduce chance of ratelimiting and improve how fast the list loads
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="hoarders-list-avatars" data-setting="AvatarsEnabled" data-parent="HoardersList" />
|
||||
<label class="form-check-label" for="hoarders-list-avatars">
|
||||
Show Avatar Icons
|
||||
<br />
|
||||
<span style="font-size: 0.6rem; color: orange;">* Avatar icons will result in more requests, potentially leading to more ratelimiting and slower hoarder list loading.</span>
|
||||
<span class="warning">
|
||||
* Avatar icons will result in more requests, potentially leading to more ratelimiting and slower hoarder list loading.
|
||||
</span>
|
||||
</label>
|
||||
</span>
|
||||
<select class="form-select form-select-sm mb-2" style="width:350px;" data-setting="MinCopies" data-parent="HoardersList" data-useValue="true">
|
||||
|
|
@ -548,12 +560,41 @@
|
|||
<option value="35">Min. 35+ Copies</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-container" id="improved-achievements">
|
||||
<span class="badge bg-primary mb-1">Now a Setting!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Improved Achievements
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ImprovedAchievements">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quality-of-life improvements to achievements!
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="progress-improved-achievements" data-setting="ProgressBarOn" data-parent="ImprovedAchievements" />
|
||||
<label class="form-check-label" for="progress-improved-achievements"> Progress Bar on All Achievements in Place </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="percentage-improved-achievements" data-setting="PercentageOn" data-parent="ImprovedAchievements" />
|
||||
<label class="form-check-label" for="percentage-improved-achievements"> Percentage of Players (& difficulty) </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="opacity-improved-achievements" data-setting="OpacityOn" data-parent="ImprovedAchievements" />
|
||||
<label class="form-check-label" for="opacity-improved-achievements"> Fade out unowned achievements </label>
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="hoarders-list">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Quick Library Downloads
|
||||
<button class="btn btn-sm toggle-btn" data-setting="LibraryDownloadsOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="LibraryDownloadsOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Quickly download a model (as a <code>.ptmd</code> file), mesh, decal, or sound right from the page showing you details about the asset!</span>
|
||||
</div>
|
||||
|
|
@ -561,8 +602,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
"Event Items" Store Category
|
||||
<button class="btn btn-sm toggle-btn" data-setting="EventItemsCatOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="EventItemsCatOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">List all the on-going and past event items separated by their event with a store category!</span>
|
||||
</div>
|
||||
|
|
@ -570,8 +613,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Show Friend Count on Homepage
|
||||
<button class="btn btn-sm toggle-btn" data-setting="HomeFriendCountOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="HomeFriendCountOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">See how many friends you have on your homepage/dashboard, just scroll to the "friends" section and you'll see it next to the heading!</span>
|
||||
</div>
|
||||
|
|
@ -579,24 +624,31 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Timed-Item Owner Check
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ItemOwnerCheckOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ItemOwnerCheckOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc"
|
||||
>Click the shopping bags icon in the bottom left-hand corner of the timed item's item thumbnail to toggle an input and a button. Then just enter someone's username and it'll tell you whether
|
||||
they own it or not and if so what serial!</span
|
||||
>
|
||||
<span class="desc">
|
||||
Click the shopping bags icon in the bottom left-hand corner of the timed item's item thumbnail to toggle an input and a button. Then just enter someone's username and it'll tell you whether
|
||||
they own it or not and if so what serial!
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="hide-user-ads">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Hide User Ads
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HideUserAds">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="HideUserAds">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Hide those annoying <s>out of context Discord message</s> user ads!</span>
|
||||
<br />
|
||||
<span class="warning">* Ads that are shown to help support Polytoria are not hidden.</span>
|
||||
<span class="desc">
|
||||
Hide those annoying <s>out of context Discord message</s> user ads!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Ads that are shown to help support Polytoria are not hidden.
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="hide-user-ads-banner" data-setting="Banners" data-parent="HideUserAds" />
|
||||
<label class="form-check-label" for="hide-user-ads-banner"> Hide Banner User Ads </label>
|
||||
|
|
@ -610,8 +662,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Multi-Decal Uploading
|
||||
<button class="btn btn-sm toggle-btn" data-setting="UploadMultipleDecals">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="UploadMultipleDecals">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quickly upload several decals all at once!
|
||||
|
|
@ -621,8 +675,10 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Avatar Dimension Toggle
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AvatarDimensionToggleOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AvatarDimensionToggleOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quickly switch between a 3D or 2D rendition of somebody's avatar on their profile page!
|
||||
|
|
@ -632,77 +688,281 @@
|
|||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
"Collectibles" Inventory Category
|
||||
<button class="btn btn-sm toggle-btn" data-setting="CollectibleInventoryCatOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="CollectibleInventoryCatOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Sort a player's inventory by all of their limited-edition collectibles!
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="value-list-info">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
"List of Values Everlast" Integration
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ValueListInfo">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quickly see a collectible's evaluation by the community-trusted "List-of-Values Everlast" guild! Credits to them for all value information provided by the extension.
|
||||
</span>
|
||||
<span class="note">
|
||||
* This feature will be expanded to allow you to pick from a list of value lists (list-inception), if any prominent value lists pop-up in the future!
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="item-view-valuation" data-setting="ItemValuation" data-parent="ValueListInfo" />
|
||||
<label class="form-check-label" for="item-view-valuation"> Show Value Info on Item View Page </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="trade-valuation" data-setting="TradeValuation" data-parent="ValueListInfo" />
|
||||
<label class="form-check-label" for="trade-valuation"> Show Value Info for all items on Trade View Page </label>
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="readd-copyable-places">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Re-add Copyable Places
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ReaddCopyablePlacesOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Download "copyable" places on Polytoria again!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* This feature does not make it possible to set your place(s) as "copyable"
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="home-join-friends">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Homepage Join Friends Tooltip Button
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="HomeJoinFriendsButtonOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Quickly join your friends' servers by clicking the play button inside the tooltip in the "Friends" section of the homepage.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="improved-place-management">
|
||||
<span class="badge bg-primary mb-1">Now a Setting!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Improved Place Management
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="Enabled" data-parent="ImprovedPlaceManagement">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Develop the next hit game easier with a few management tools!
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="quick-activity-toggle" data-setting="QuickActivityToggleOn" data-parent="ImprovedPlaceManagement" />
|
||||
<label class="form-check-label" for="quick-activity-toggle"> Quick Place Activity Toggle </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="download-place-file-button" data-setting="PlaceFileDownloadOn" data-parent="ImprovedPlaceManagement" />
|
||||
<label class="form-check-label" for="download-place-file-button"> Download Place File Button </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="multi-whitelist" data-setting="MultiWhitelistOn" data-parent="ImprovedPlaceManagement" />
|
||||
<label class="form-check-label" for="multi-whitelist"> <span class="badge bg-primary mb-1">New in v1.3!</span> Multi-Whitelist Several Users </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="clear-whitelist-button" data-setting="ClearWhitelistOn" data-parent="ImprovedPlaceManagement" />
|
||||
<label class="form-check-label" for="clear-whitelist-button"> <span class="badge bg-primary mb-1">New in v1.3!</span> Quick Clear Whitelist Button </label>
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="more-blocked-details">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
See Player ID and Join Date when Blocked
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="MoreBlockedDetailsOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
See someone's player ID and join date even if they have blocked you on their profile.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="asset-designer-credit">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Asset Designer Credit
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AssetDesignerCreditOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Check who modeled the item you're looking at on the item view page! If the text doesn't show up next to the sales counter, make sure to DM me so I can add whoever modeled that item.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="avatar-sandbox">
|
||||
<span class="badge bg-primary mb-1">Finished & No longer Experimental in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Avatar Sandbox
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AvatarSandboxOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">
|
||||
Create an avatar with all the item possibilities available to your heart's content!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* This feature is not polished - things like modifying avatar "Body Colors", pagination, outfits, etc haven't been added.
|
||||
</span>
|
||||
</div>
|
||||
<!---
|
||||
coming soon maybe I don't know, I'm lazy
|
||||
<div class="setting-container" id="auto-ad-bidding">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Automatic Ad Bidding
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AutoAdBiddingOn">Toggle</button>
|
||||
<button class="btn btn-primary btn-sm" data-modal="AutoAdBidding">Options</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-primary btn-sm" data-modal="AutoAdBidding">Options</button>
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AutoAdBiddingOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">description</span>
|
||||
</div>
|
||||
-->
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h3>ARCHIVED SETTINGS</h3>
|
||||
<p>Features here still work, but are separated from other features as they will no longer receive any improvements, or changes (bugs however may be fixed eventually if any are found).</p>
|
||||
<hr />
|
||||
<div class="card card-body limited-time setting-container mb-3 enabled" id="greatdivide-server-unbalance" style="background-image: linear-gradient(rgba(0.8, 0.8, 0.8, 0.8), rgba(0.8, 0.8, 0.8, 0.8)), url(/images/greatdivide.png); background-size: cover; background-position: center;">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<span class="indicator"> </span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="title">
|
||||
The Great Divide
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn btn-danger" data-setting="Enabled" data-parent="TheGreatDivide">Disable</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="desc">Reinforcements to aid in your quest to bring home the victory to your team, and bring honor to your peers.</span>
|
||||
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="server-unbalanced-greatdivide" data-setting="UnbalancedIndicatorOn" data-parent="TheGreatDivide">
|
||||
<label class="form-check-label" for="server-unbalanced-greatdivide">"Potentially Unbalanced" indicator in server list </label>
|
||||
</span>
|
||||
<span class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="user-statistics-greatdivide" data-setting="UserStatsOn" data-parent="TheGreatDivide">
|
||||
<label class="form-check-label" for="user-statistics-greatdivide">User Statistics tab on profiles</label>
|
||||
</span>
|
||||
|
||||
<small class="text-muted mt-1" style="font-size: 0.7rem;">
|
||||
* features use <a href="https://polytoria.com/u/dargy" target="_blank">@dargy</a>'s public API! thank you!
|
||||
</small>
|
||||
<small class="limited-time-tag mt-1">
|
||||
* was available until July 14th
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3>EXPERIMENTAL SETTINGS</h3>
|
||||
<p>These features are a work in progress.</p>
|
||||
<hr />
|
||||
<div class="setting-container" id="game-profiles">
|
||||
<div class="setting-container" id="time-played">
|
||||
<span class="badge bg-primary mb-1">New in v1.3!</span>
|
||||
<br>
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Game Profiles
|
||||
<button class="btn btn-sm toggle-btn" data-setting="GameProfilesOn">Toggle</button>
|
||||
Time Played
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="TimePlayedOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Traverse a place view page that matches a place's color palette!</span>
|
||||
<br />
|
||||
<span class="warning">* Place creators must request a game profile for one to be made.</span>
|
||||
<br />
|
||||
<span class="warning">* This feature will be expanded upon in the future.</span>
|
||||
<span class="desc">
|
||||
Track your playtime in places around Polytoria!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Past playtime data (prior to extension install/prior to setting enable) is, understandably, not able to be tracked
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="inline-editing">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Inline Editing
|
||||
<button class="btn btn-sm toggle-btn" data-setting="InlineEditingOn">Toggle</button>
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="InlineEditingOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="desc">Quickly edit your asset's details such as name and description on the same page as viewing the asset!</span>
|
||||
<span class="warning">
|
||||
* This feature only supports places at this time.
|
||||
</span>
|
||||
<span class="warning">
|
||||
* This feature is not finished or polished.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="game-profiles">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Game Profiles
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="GameProfilesOn">Toggle</button>
|
||||
</div>
|
||||
<br />
|
||||
<span class="warning">* This feature currently only supports places.</span>
|
||||
<br />
|
||||
<span class="warning">* This feature is not finished or polished.</span>
|
||||
<span class="desc">
|
||||
Traverse a place view page that matches a place's color palette!
|
||||
</span>
|
||||
<span class="warning">
|
||||
* Place creators must request a game profile for one to be made.
|
||||
</span>
|
||||
<span class="warning">
|
||||
* This feature will be expanded upon in the future.
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-container" id="forum-unix-timestamps">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Forum Unix Timestamps
|
||||
</span>
|
||||
<div class="setting-buttons">
|
||||
<button class="btn btn-sm toggle-btn" data-setting="ForumUnixStampsOn">Toggle</button>
|
||||
</span>
|
||||
<br />
|
||||
<span class="desc">See a date and time that is adjusted to everyone (who is using Poly+)'s local time</span>
|
||||
<br />
|
||||
<span class="warning">* The styling for this feature is not yet done.</span>
|
||||
</div>
|
||||
<div class="setting-container" id="avatar-sandbox">
|
||||
<span class="indicator"> </span>
|
||||
<span class="title">
|
||||
Avatar Sandbox
|
||||
<button class="btn btn-sm toggle-btn" data-setting="AvatarSandboxOn">Toggle</button>
|
||||
<br />
|
||||
<span class="desc">
|
||||
See a date and time that is adjusted to everyone (who is using Poly+)'s local time.
|
||||
</span>
|
||||
<span class="warning">
|
||||
* The styling for this feature is not yet done.
|
||||
</span>
|
||||
<br />
|
||||
<span class="desc">Create an avatar with all the item possibilities available to your heart's content!</span>
|
||||
<br />
|
||||
<span class="warning">* This feature is not polished - things like modifying avatar "Body Colors", pagination, outfits, etc haven't been added.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
16
settings.js
16
settings.js
|
|
@ -11,9 +11,9 @@ var Utilities;
|
|||
LoadCurrent();
|
||||
|
||||
document.getElementById('PinnedGames-limit').innerText = Utilities.Limits.PinnedGames;
|
||||
document.getElementById('BestFriends-limit').innerText = Utilities.Limits.BestFriends;
|
||||
document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists;
|
||||
//document.getElementById('ImprovedFrLists-limit').innerText = Utilities.Limits.ImprovedFrLists;
|
||||
//document.getElementById('ItemWishlist-limit').innerText = Utilities.Limits.ItemWishlist;
|
||||
document.getElementById('HoardersList-pageLimit').innerText = Utilities.Limits.HoardersListPages;
|
||||
})();
|
||||
|
||||
// Handle buttons at the bottom of the page
|
||||
|
|
@ -37,10 +37,10 @@ document.getElementById('ResetDefaults-Modal-No').addEventListener('click', func
|
|||
|
||||
// Loop thru each setting container and handle toggling, selecting, opening modal, etc
|
||||
Elements.forEach((element) => {
|
||||
let Button = element.getElementsByTagName('button')[0];
|
||||
let Options = element.getElementsByTagName('button')[1];
|
||||
let Button = element.getElementsByClassName('toggle-btn')[0];
|
||||
let Options = element.getElementsByClassName('options-btn')[0];
|
||||
let Select = element.getElementsByTagName('select')[0];
|
||||
let Checkbox = element.getElementsByTagName('input')[0];
|
||||
let Checkbox = element.getElementsByTagName('input');
|
||||
|
||||
if (Button) {
|
||||
Button.addEventListener('click', function () {
|
||||
|
|
@ -63,9 +63,11 @@ Elements.forEach((element) => {
|
|||
}
|
||||
|
||||
if (Checkbox) {
|
||||
Checkbox.addEventListener('change', function () {
|
||||
SetSetting(Checkbox, Checkbox.checked, false);
|
||||
Array.from(Checkbox).forEach(check => {
|
||||
check.addEventListener('change', function () {
|
||||
SetSetting(check, check.checked, false);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
if (Options) {
|
||||
|
|
|
|||
|
|
@ -1,127 +0,0 @@
|
|||
chrome.storage.sync.get(['PolyPlus_Settings'], function(result) {
|
||||
Settings = result.PolyPlus_Settings || {};
|
||||
|
||||
if (Settings.TheGreatDivide.Enabled !== true) {
|
||||
return
|
||||
}
|
||||
|
||||
let EventOngoing = true
|
||||
let HasTeam = true
|
||||
if (document.querySelector('#user-avatar-card a[href="/event/the-great-divide"]') === null) { HasTeam = false }
|
||||
if (new Date().getMonth().toString()+new Date().getDate().toString() >= 714) { EventOngoing = false }
|
||||
|
||||
if (Settings.TheGreatDivide.UnbalancedIndicatorOn === true && window.location.pathname.split('/')[1] === 'places' && window.location.pathname.split('/')[2] === '9656') {
|
||||
UnbalancedServerMarkers()
|
||||
}
|
||||
|
||||
console.log('ongoing|has team', EventOngoing, HasTeam)
|
||||
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 Tabs = document.getElementById('user-info-tabs')
|
||||
|
||||
const EventTab = document.createElement('li')
|
||||
EventTab.classList = 'nav-item'
|
||||
EventTab.style.marginLeft = 'auto'
|
||||
EventTab.innerHTML = `
|
||||
<a class="nav-link fw-semibold" href="#!" aria-selected="false" tabindex="-1" role="tab" style="background-clip:text;-webkit-background-clip:text;color:transparent;background-image: linear-gradient(90deg, #1ad05b, #68f);-webkit-text-fill-color: transparent;">
|
||||
<img style="width: 25px;height: auto;" src="https://c0.ptacdn.com/static/images/misc/event/dpoint.af12a3d7.png">
|
||||
Great Divide
|
||||
</a>
|
||||
`
|
||||
Tabs.appendChild(EventTab)
|
||||
|
||||
const TabContainer = document.createElement('div')
|
||||
TabContainer.id = 'p+greatdivide_stats'
|
||||
TabContainer.classList = 'tab-pane fade d-none'
|
||||
TabContainer.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>
|
||||
`
|
||||
document.getElementById('user-friends').parentElement.appendChild(TabContainer)
|
||||
|
||||
const ToggleTab = function(tab){
|
||||
Array.from(Tabs.children).forEach((tab) => {
|
||||
tab.children[0].classList.remove('active');
|
||||
});
|
||||
Array.from(document.getElementById('user-friends').parentElement.children).forEach((tab) => {
|
||||
tab.classList.add('d-none');
|
||||
tab.classList.remove('active');
|
||||
tab.classList.remove('show');
|
||||
});
|
||||
tab.children[0].classList.add('active');
|
||||
|
||||
let SelectedTab
|
||||
if (tab.children[0].getAttribute('data-bs-target')) {
|
||||
SelectedTab = document.getElementById(tab.children[0].getAttribute('data-bs-target').substring(1))
|
||||
} else {
|
||||
SelectedTab = TabContainer
|
||||
}
|
||||
SelectedTab.classList.add('active');
|
||||
SelectedTab.classList.add('show');
|
||||
SelectedTab.classList.remove('d-none');
|
||||
}
|
||||
|
||||
Array.from(Tabs.children).forEach((tab) => {
|
||||
tab.addEventListener('click', function () {
|
||||
ToggleTab(tab)
|
||||
});
|
||||
});
|
||||
|
||||
let Fetched = false
|
||||
EventTab.addEventListener('click', async function(){
|
||||
if (Fetched === false) {
|
||||
chrome.runtime.sendMessage({
|
||||
action: "greatdivide_stats",
|
||||
username: window.location.pathname.split('/')[2]
|
||||
});
|
||||
Fetched = true
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in a new issue