@scarlett-player/playlist 1.8.1 → 1.9.0
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/dist/index.cjs +30 -15
- package/dist/index.js +32 -15
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
default: () => index_default
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
var import_core2 = require("@scarlett-player/core");
|
|
40
41
|
|
|
41
42
|
// src/controls.ts
|
|
42
43
|
var PLAYLIST_ICONS = {
|
|
@@ -197,6 +198,7 @@ var PlaylistPanel = class {
|
|
|
197
198
|
};
|
|
198
199
|
|
|
199
200
|
// src/styles.ts
|
|
201
|
+
var import_core = require("@scarlett-player/core");
|
|
200
202
|
var STYLE_ID = "sp-playlist-styles";
|
|
201
203
|
var styles = `
|
|
202
204
|
.sp-playlist-skip[disabled] {
|
|
@@ -298,18 +300,11 @@ var styles = `
|
|
|
298
300
|
}
|
|
299
301
|
`;
|
|
300
302
|
function injectStyles() {
|
|
301
|
-
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
const el = document.createElement("style");
|
|
305
|
-
el.id = STYLE_ID;
|
|
306
|
-
el.textContent = styles;
|
|
307
|
-
document.head.appendChild(el);
|
|
308
|
-
return el;
|
|
303
|
+
return (0, import_core.injectSharedStyles)(STYLE_ID, styles);
|
|
309
304
|
}
|
|
310
305
|
|
|
311
306
|
// src/version.ts
|
|
312
|
-
var PKG_VERSION = true ? "1.
|
|
307
|
+
var PKG_VERSION = true ? "1.9.0" : "0.0.0-dev";
|
|
313
308
|
|
|
314
309
|
// src/index.ts
|
|
315
310
|
var DEFAULT_CONFIG = {
|
|
@@ -336,6 +331,9 @@ function shuffleArray(array) {
|
|
|
336
331
|
function createPlaylistPlugin(config) {
|
|
337
332
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
338
333
|
let api = null;
|
|
334
|
+
let releaseStyles = null;
|
|
335
|
+
let releaseControls = null;
|
|
336
|
+
let lifecycle = 0;
|
|
339
337
|
let tracks = mergedConfig.tracks || [];
|
|
340
338
|
let currentIndex = mergedConfig.initialIndex ?? -1;
|
|
341
339
|
if (currentIndex < -1 || currentIndex >= tracks.length) {
|
|
@@ -458,7 +456,7 @@ function createPlaylistPlugin(config) {
|
|
|
458
456
|
}
|
|
459
457
|
const track = tracks[index];
|
|
460
458
|
currentIndex = index;
|
|
461
|
-
api?.logger.info("Track changed", { index, title: track.title, src: track.src });
|
|
459
|
+
api?.logger.info("Track changed", { index, title: track.title, src: (0, import_core2.sanitizeUrl)(track.src) });
|
|
462
460
|
api?.setState("title", track.title || "");
|
|
463
461
|
api?.setState("poster", track.artwork || "");
|
|
464
462
|
api?.setState("mediaType", track.type || "audio");
|
|
@@ -474,6 +472,7 @@ function createPlaylistPlugin(config) {
|
|
|
474
472
|
type: "feature",
|
|
475
473
|
description: "Playlist management with shuffle, repeat, and gapless playback",
|
|
476
474
|
async init(pluginApi) {
|
|
475
|
+
const generation = ++lifecycle;
|
|
477
476
|
api = pluginApi;
|
|
478
477
|
api.logger.info("Playlist plugin initialized");
|
|
479
478
|
loadPersistedPlaylist();
|
|
@@ -499,20 +498,31 @@ function createPlaylistPlugin(config) {
|
|
|
499
498
|
api?.emit("playlist:ended", void 0);
|
|
500
499
|
}
|
|
501
500
|
});
|
|
502
|
-
injectStyles();
|
|
503
|
-
|
|
501
|
+
releaseStyles = injectStyles();
|
|
502
|
+
const owner = api.container;
|
|
503
|
+
void import("@scarlett-player/ui").then(({ registerControl, unregisterControl }) => {
|
|
504
|
+
if (generation !== lifecycle) return;
|
|
504
505
|
const self = plugin;
|
|
505
506
|
registerControl(
|
|
506
507
|
"playlist-previous",
|
|
507
|
-
() => new PlaylistSkipButton(self, "previous")
|
|
508
|
+
() => new PlaylistSkipButton(self, "previous"),
|
|
509
|
+
{ owner }
|
|
508
510
|
);
|
|
509
|
-
registerControl("playlist-next", () => new PlaylistSkipButton(self, "next")
|
|
511
|
+
registerControl("playlist-next", () => new PlaylistSkipButton(self, "next"), {
|
|
512
|
+
owner
|
|
513
|
+
});
|
|
510
514
|
registerControl(
|
|
511
515
|
"playlist",
|
|
512
516
|
() => new PlaylistPanel(self, {
|
|
513
517
|
onSelect: (index) => self.play(index)
|
|
514
|
-
})
|
|
518
|
+
}),
|
|
519
|
+
{ owner }
|
|
515
520
|
);
|
|
521
|
+
releaseControls = () => {
|
|
522
|
+
unregisterControl("playlist-previous", { owner });
|
|
523
|
+
unregisterControl("playlist-next", { owner });
|
|
524
|
+
unregisterControl("playlist", { owner });
|
|
525
|
+
};
|
|
516
526
|
}).catch(() => {
|
|
517
527
|
api?.logger.debug("@scarlett-player/ui not present, playlist controls not registered");
|
|
518
528
|
});
|
|
@@ -543,8 +553,13 @@ function createPlaylistPlugin(config) {
|
|
|
543
553
|
});
|
|
544
554
|
},
|
|
545
555
|
async destroy() {
|
|
556
|
+
lifecycle++;
|
|
546
557
|
api?.logger.info("Playlist plugin destroying");
|
|
547
558
|
persistPlaylist();
|
|
559
|
+
releaseStyles?.();
|
|
560
|
+
releaseStyles = null;
|
|
561
|
+
releaseControls?.();
|
|
562
|
+
releaseControls = null;
|
|
548
563
|
api = null;
|
|
549
564
|
},
|
|
550
565
|
add(trackOrTracks) {
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { sanitizeUrl } from "@scarlett-player/core";
|
|
3
|
+
|
|
1
4
|
// src/controls.ts
|
|
2
5
|
var PLAYLIST_ICONS = {
|
|
3
6
|
previous: '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 6h2v12H6V6zm3.5 6L18 6v12l-8.5-6z"/></svg>',
|
|
@@ -157,6 +160,7 @@ var PlaylistPanel = class {
|
|
|
157
160
|
};
|
|
158
161
|
|
|
159
162
|
// src/styles.ts
|
|
163
|
+
import { injectSharedStyles } from "@scarlett-player/core";
|
|
160
164
|
var STYLE_ID = "sp-playlist-styles";
|
|
161
165
|
var styles = `
|
|
162
166
|
.sp-playlist-skip[disabled] {
|
|
@@ -258,18 +262,11 @@ var styles = `
|
|
|
258
262
|
}
|
|
259
263
|
`;
|
|
260
264
|
function injectStyles() {
|
|
261
|
-
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
const el = document.createElement("style");
|
|
265
|
-
el.id = STYLE_ID;
|
|
266
|
-
el.textContent = styles;
|
|
267
|
-
document.head.appendChild(el);
|
|
268
|
-
return el;
|
|
265
|
+
return injectSharedStyles(STYLE_ID, styles);
|
|
269
266
|
}
|
|
270
267
|
|
|
271
268
|
// src/version.ts
|
|
272
|
-
var PKG_VERSION = true ? "1.
|
|
269
|
+
var PKG_VERSION = true ? "1.9.0" : "0.0.0-dev";
|
|
273
270
|
|
|
274
271
|
// src/index.ts
|
|
275
272
|
var DEFAULT_CONFIG = {
|
|
@@ -296,6 +293,9 @@ function shuffleArray(array) {
|
|
|
296
293
|
function createPlaylistPlugin(config) {
|
|
297
294
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
298
295
|
let api = null;
|
|
296
|
+
let releaseStyles = null;
|
|
297
|
+
let releaseControls = null;
|
|
298
|
+
let lifecycle = 0;
|
|
299
299
|
let tracks = mergedConfig.tracks || [];
|
|
300
300
|
let currentIndex = mergedConfig.initialIndex ?? -1;
|
|
301
301
|
if (currentIndex < -1 || currentIndex >= tracks.length) {
|
|
@@ -418,7 +418,7 @@ function createPlaylistPlugin(config) {
|
|
|
418
418
|
}
|
|
419
419
|
const track = tracks[index];
|
|
420
420
|
currentIndex = index;
|
|
421
|
-
api?.logger.info("Track changed", { index, title: track.title, src: track.src });
|
|
421
|
+
api?.logger.info("Track changed", { index, title: track.title, src: sanitizeUrl(track.src) });
|
|
422
422
|
api?.setState("title", track.title || "");
|
|
423
423
|
api?.setState("poster", track.artwork || "");
|
|
424
424
|
api?.setState("mediaType", track.type || "audio");
|
|
@@ -434,6 +434,7 @@ function createPlaylistPlugin(config) {
|
|
|
434
434
|
type: "feature",
|
|
435
435
|
description: "Playlist management with shuffle, repeat, and gapless playback",
|
|
436
436
|
async init(pluginApi) {
|
|
437
|
+
const generation = ++lifecycle;
|
|
437
438
|
api = pluginApi;
|
|
438
439
|
api.logger.info("Playlist plugin initialized");
|
|
439
440
|
loadPersistedPlaylist();
|
|
@@ -459,20 +460,31 @@ function createPlaylistPlugin(config) {
|
|
|
459
460
|
api?.emit("playlist:ended", void 0);
|
|
460
461
|
}
|
|
461
462
|
});
|
|
462
|
-
injectStyles();
|
|
463
|
-
|
|
463
|
+
releaseStyles = injectStyles();
|
|
464
|
+
const owner = api.container;
|
|
465
|
+
void import("@scarlett-player/ui").then(({ registerControl, unregisterControl }) => {
|
|
466
|
+
if (generation !== lifecycle) return;
|
|
464
467
|
const self = plugin;
|
|
465
468
|
registerControl(
|
|
466
469
|
"playlist-previous",
|
|
467
|
-
() => new PlaylistSkipButton(self, "previous")
|
|
470
|
+
() => new PlaylistSkipButton(self, "previous"),
|
|
471
|
+
{ owner }
|
|
468
472
|
);
|
|
469
|
-
registerControl("playlist-next", () => new PlaylistSkipButton(self, "next")
|
|
473
|
+
registerControl("playlist-next", () => new PlaylistSkipButton(self, "next"), {
|
|
474
|
+
owner
|
|
475
|
+
});
|
|
470
476
|
registerControl(
|
|
471
477
|
"playlist",
|
|
472
478
|
() => new PlaylistPanel(self, {
|
|
473
479
|
onSelect: (index) => self.play(index)
|
|
474
|
-
})
|
|
480
|
+
}),
|
|
481
|
+
{ owner }
|
|
475
482
|
);
|
|
483
|
+
releaseControls = () => {
|
|
484
|
+
unregisterControl("playlist-previous", { owner });
|
|
485
|
+
unregisterControl("playlist-next", { owner });
|
|
486
|
+
unregisterControl("playlist", { owner });
|
|
487
|
+
};
|
|
476
488
|
}).catch(() => {
|
|
477
489
|
api?.logger.debug("@scarlett-player/ui not present, playlist controls not registered");
|
|
478
490
|
});
|
|
@@ -503,8 +515,13 @@ function createPlaylistPlugin(config) {
|
|
|
503
515
|
});
|
|
504
516
|
},
|
|
505
517
|
async destroy() {
|
|
518
|
+
lifecycle++;
|
|
506
519
|
api?.logger.info("Playlist plugin destroying");
|
|
507
520
|
persistPlaylist();
|
|
521
|
+
releaseStyles?.();
|
|
522
|
+
releaseStyles = null;
|
|
523
|
+
releaseControls?.();
|
|
524
|
+
releaseControls = null;
|
|
508
525
|
api = null;
|
|
509
526
|
},
|
|
510
527
|
add(trackOrTracks) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scarlett-player/playlist",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Playlist Plugin for Scarlett Player - Queue management, shuffle, repeat, and gapless playback",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"typescript": "^5.3.0",
|
|
31
31
|
"vitest": "^1.6.0",
|
|
32
32
|
"jsdom": "^24.0.0",
|
|
33
|
-
"@scarlett-player/core": "1.
|
|
34
|
-
"@scarlett-player/ui": "1.
|
|
33
|
+
"@scarlett-player/core": "1.9.0",
|
|
34
|
+
"@scarlett-player/ui": "1.9.0"
|
|
35
35
|
},
|
|
36
36
|
"keywords": [
|
|
37
37
|
"video",
|
|
@@ -65,6 +65,6 @@
|
|
|
65
65
|
"dev": "tsup --watch",
|
|
66
66
|
"test": "vitest --run",
|
|
67
67
|
"test:watch": "vitest",
|
|
68
|
-
"typecheck": "tsc --noEmit"
|
|
68
|
+
"typecheck": "tsc --noEmit -p tsconfig.typecheck.json"
|
|
69
69
|
}
|
|
70
70
|
}
|