perfectionist-plugins 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -14
- package/hide-unowned-skins.js +36 -15
- package/package.json +1 -1
- package/perfectionist-utils.js +2 -6
package/README.md
CHANGED
|
@@ -48,31 +48,19 @@ Built for [Pengu Loader](https://pengu.lol)
|
|
|
48
48
|
2. Move the `Perfectionism` folder into your Pengu Loader `plugins` folder.
|
|
49
49
|
3. Restart the League Client.
|
|
50
50
|
|
|
51
|
-
That's it. The folder holds one tiny loader file
|
|
51
|
+
That's it. The folder holds one tiny loader file. The plugins themselves come from the
|
|
52
52
|
[`perfectionist-plugins`](https://www.npmjs.com/package/perfectionist-plugins) npm package the
|
|
53
53
|
first time the client starts. Install, remove and toggle plugins in **Settings → Perfectionism**.
|
|
54
54
|
|
|
55
|
-
<br>
|
|
56
|
-
|
|
57
55
|
## Updates
|
|
58
56
|
|
|
59
|
-
Every time the client starts, the loader checks npm for a newer version and runs it
|
|
57
|
+
Every time the client starts, the loader checks npm for a newer version and runs it. Publishing
|
|
60
58
|
a new version of the npm package **is** the update. If a new version appears while the client is
|
|
61
59
|
already open, the suite downloads it with a progress window and restarts the client at a safe
|
|
62
60
|
moment (never in the middle of a game). You never replace files by hand.
|
|
63
61
|
|
|
64
62
|
<br>
|
|
65
63
|
|
|
66
|
-
## Publishing an update (maintainers)
|
|
67
|
-
|
|
68
|
-
1. Bump `version` in `package.json`.
|
|
69
|
-
2. Run `npm publish` from the repo root (first time only: `npm login` first).
|
|
70
|
-
|
|
71
|
-
That's the whole release process — every install picks the new version up on its own. Never edit
|
|
72
|
-
anything inside the `Perfectionism` folder: that one file stays the same for everyone.
|
|
73
|
-
|
|
74
|
-
<br>
|
|
75
|
-
|
|
76
64
|
---
|
|
77
65
|
|
|
78
66
|
<div align="center">
|
package/hide-unowned-skins.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const version = "2.
|
|
1
|
+
export const version = "2.2.0";
|
|
2
2
|
|
|
3
3
|
const PLUGIN_ID = "hide-unowned-skins";
|
|
4
4
|
const STYLE_ID = "perfectionist-hide-unowned-skins-style";
|
|
@@ -11,7 +11,7 @@ const CAROUSEL_URI = "/lol-champ-select/v1/skin-carousel-skins";
|
|
|
11
11
|
const CURRENT_SUMMONER_URI = "/lol-summoner/v1/current-summoner";
|
|
12
12
|
const SUMMONER_TTL = 10 * 60 * 1000;
|
|
13
13
|
const INVENTORY_TTL = 60 * 1000;
|
|
14
|
-
const
|
|
14
|
+
const REFRESH_DEBOUNCE_MS = 350;
|
|
15
15
|
const RETRY_MS = 5000;
|
|
16
16
|
const STATE_KEY = "perfectionist-plugins:state";
|
|
17
17
|
|
|
@@ -34,7 +34,7 @@ let clientSkinOrder = [];
|
|
|
34
34
|
function readDefaultEnabled() {
|
|
35
35
|
try {
|
|
36
36
|
const saved = JSON.parse(localStorage.getItem(STATE_KEY) || "{}");
|
|
37
|
-
return saved[PLUGIN_ID] !== false;
|
|
37
|
+
return saved.enabled?.[PLUGIN_ID] !== false;
|
|
38
38
|
} catch {
|
|
39
39
|
return true;
|
|
40
40
|
}
|
|
@@ -57,6 +57,7 @@ function filterSkinList(list) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function recordClientOrder(list) {
|
|
60
|
+
scheduleRefresh();
|
|
60
61
|
if (Array.isArray(list)) {
|
|
61
62
|
clientSkinOrder = list.map((skin) => (skin && typeof skin.id === "number" ? skin.id : null)).filter((id) => id !== null);
|
|
62
63
|
}
|
|
@@ -262,7 +263,8 @@ let carouselOrder = [];
|
|
|
262
263
|
let selectedSkinId = null;
|
|
263
264
|
let failure = null;
|
|
264
265
|
let requestToken = 0;
|
|
265
|
-
let
|
|
266
|
+
let refreshTimer = null;
|
|
267
|
+
let unsubscribe = null;
|
|
266
268
|
let pollInFlight = false;
|
|
267
269
|
let selectInFlight = false;
|
|
268
270
|
let sessionMisses = 0;
|
|
@@ -452,7 +454,7 @@ function resetState() {
|
|
|
452
454
|
failure = null;
|
|
453
455
|
sessionMisses = 0;
|
|
454
456
|
championMisses = 0;
|
|
455
|
-
|
|
457
|
+
applyAllGuarded();
|
|
456
458
|
}
|
|
457
459
|
|
|
458
460
|
function loadChampion(championId) {
|
|
@@ -467,7 +469,7 @@ function loadChampion(championId) {
|
|
|
467
469
|
if (token !== requestToken) return;
|
|
468
470
|
ownedSkinIds = owned;
|
|
469
471
|
carouselOrder = carouselIds.length > 0 ? carouselIds : inventoryOrder;
|
|
470
|
-
|
|
472
|
+
applyAllGuarded();
|
|
471
473
|
},
|
|
472
474
|
(error) => {
|
|
473
475
|
if (token !== requestToken) return;
|
|
@@ -507,7 +509,23 @@ function updateForSession(session, selection) {
|
|
|
507
509
|
}
|
|
508
510
|
}
|
|
509
511
|
|
|
510
|
-
|
|
512
|
+
applyAllGuarded();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function scheduleRefresh() {
|
|
516
|
+
clearTimeout(refreshTimer);
|
|
517
|
+
refreshTimer = setTimeout(pollSession, REFRESH_DEBOUNCE_MS);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function onSessionPush(raw) {
|
|
521
|
+
const msg = raw ?? {};
|
|
522
|
+
if (msg.eventType === "Delete") {
|
|
523
|
+
resetState();
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const s = msg.data ?? msg;
|
|
527
|
+
if (!s?.myTeam) return;
|
|
528
|
+
updateForSession(s, null);
|
|
511
529
|
}
|
|
512
530
|
|
|
513
531
|
async function pollSession() {
|
|
@@ -515,11 +533,9 @@ async function pollSession() {
|
|
|
515
533
|
ensureSourceFilter();
|
|
516
534
|
pollInFlight = true;
|
|
517
535
|
try {
|
|
518
|
-
const
|
|
519
|
-
api.lcu.get(SESSION_URI),
|
|
520
|
-
api.lcu.get(SELECTION_URI).catch(() => null),
|
|
521
|
-
]);
|
|
536
|
+
const session = await api.lcu.get(SESSION_URI);
|
|
522
537
|
sessionMisses = 0;
|
|
538
|
+
const selection = await api.lcu.get(SELECTION_URI).catch(() => null);
|
|
523
539
|
updateForSession(session, selection);
|
|
524
540
|
} catch {
|
|
525
541
|
sessionMisses++;
|
|
@@ -534,16 +550,21 @@ function onEnable(utils) {
|
|
|
534
550
|
filterActive = true;
|
|
535
551
|
removeStyle = api.addStyle(STYLE_ID, CSS);
|
|
536
552
|
|
|
537
|
-
renderObserver = new MutationObserver(() =>
|
|
553
|
+
renderObserver = new MutationObserver(() => {
|
|
554
|
+
applyAllGuarded();
|
|
555
|
+
if (document.querySelector(SKIN_ITEM_SELECTOR)) scheduleRefresh();
|
|
556
|
+
});
|
|
538
557
|
renderObserver.observe(document.documentElement ?? document, OBSERVER_OPTIONS);
|
|
539
558
|
|
|
540
|
-
|
|
559
|
+
unsubscribe = api.subscribe(SESSION_URI, onSessionPush);
|
|
541
560
|
pollSession();
|
|
542
561
|
}
|
|
543
562
|
|
|
544
563
|
function onDisable() {
|
|
545
|
-
|
|
546
|
-
|
|
564
|
+
unsubscribe?.();
|
|
565
|
+
unsubscribe = null;
|
|
566
|
+
clearTimeout(refreshTimer);
|
|
567
|
+
refreshTimer = null;
|
|
547
568
|
renderObserver?.disconnect();
|
|
548
569
|
removeStyle?.();
|
|
549
570
|
renderObserver = null;
|
package/package.json
CHANGED
package/perfectionist-utils.js
CHANGED
|
@@ -33,7 +33,7 @@ const BUNDLED_MODULES = [
|
|
|
33
33
|
id: "hide-unowned-skins",
|
|
34
34
|
file: "hide-unowned-skins.js",
|
|
35
35
|
name: "Hide Unowned Skins",
|
|
36
|
-
version: "2.
|
|
36
|
+
version: "2.2.0",
|
|
37
37
|
description: "In champion select, only shows the skins you own for the picked champion.",
|
|
38
38
|
},
|
|
39
39
|
];
|
|
@@ -113,11 +113,6 @@ async function loadState() {
|
|
|
113
113
|
state = { installed: saved.installed, enabled: saved.enabled ?? {} };
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
for (const mod of BUNDLED_MODULES) {
|
|
117
|
-
if (mod.core) continue;
|
|
118
|
-
state.installed[mod.id] = true;
|
|
119
|
-
state.enabled[mod.id] = mod.defaultEnabled ?? true;
|
|
120
|
-
}
|
|
121
116
|
saveState();
|
|
122
117
|
}
|
|
123
118
|
|
|
@@ -315,6 +310,7 @@ async function runUpdate(target) {
|
|
|
315
310
|
win.setProgress(i / files.length);
|
|
316
311
|
try {
|
|
317
312
|
const response = await fetch(`${CDN}/${PKG}@${target}/${files[i].file}`);
|
|
313
|
+
if (response.status === 404 && files[i].id) continue;
|
|
318
314
|
if (!response.ok) throw new Error(`download failed (${response.status})`);
|
|
319
315
|
const text = await response.text();
|
|
320
316
|
if (!text || !/export/.test(text)) throw new Error("the downloaded file looks invalid");
|