@gentomiyano/optimized-web-audio-player 0.1.0 → 0.2.1
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 +189 -159
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/consumer/index.d.ts +1 -1
- package/dist/consumer/index.js.map +1 -1
- package/dist/contracts/index.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/media-delivery/index.d.ts +1 -1
- package/dist/media-delivery/index.js.map +1 -1
- package/dist/{media-element-C9dis4aG.d.ts → media-element-DyMO-PhK.d.ts} +1 -1
- package/dist/{player-DE9Vqztu.d.ts → player-BxNFzRq4.d.ts} +53 -1
- package/dist/ports/index.d.ts +2 -2
- package/dist/react/index.d.ts +22 -3
- package/dist/react/index.js +721 -12
- package/dist/react/index.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/ui/index.d.ts +18 -2
- package/dist/ui/index.js +148 -55
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/player-tokens.css +572 -572
- package/dist/ui/player-views.css +713 -654
- package/dist/ui/styles.css +2 -2
- package/package.json +14 -3
- package/dist/consumer-smoke/node_modules/.modules.yaml +0 -30
- package/dist/consumer-smoke/node_modules/.package-map.json +0 -1
- package/dist/consumer-smoke/node_modules/.pnpm/lock.yaml +0 -57
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/LICENSE +0 -21
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/README.md +0 -9
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +0 -414
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_mock.production.js +0 -406
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js +0 -150
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler-unstable_post_task.production.js +0 -140
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.development.js +0 -364
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.native.development.js +0 -350
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.native.production.js +0 -330
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/cjs/scheduler.production.js +0 -340
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/index.js +0 -7
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/index.native.js +0 -7
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/package.json +0 -27
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/unstable_mock.js +0 -7
- package/dist/consumer-smoke/node_modules/.pnpm/scheduler@0.27.0/node_modules/scheduler/unstable_post_task.js +0 -7
- package/dist/consumer-smoke/node_modules/.pnpm-workspace-state-v1.json +0 -29
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useRef, useState, useEffect, useSyncExternalStore, useContext } from 'react';
|
|
1
|
+
import { createContext, useRef, useState, useEffect, useSyncExternalStore, useMemo, useContext, useId } from 'react';
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/react/player-provider.tsx
|
|
@@ -845,6 +845,7 @@ function createInitialPlayerState(experienceConfig) {
|
|
|
845
845
|
shuffleEnabled: resolved.value.initialShuffleEnabled,
|
|
846
846
|
repeatMode: resolved.value.initialRepeatMode,
|
|
847
847
|
queue: Object.freeze([]),
|
|
848
|
+
activeContext: null,
|
|
848
849
|
currentQueueIndex: null,
|
|
849
850
|
canSeek: false,
|
|
850
851
|
canGoPrevious: false,
|
|
@@ -995,16 +996,32 @@ function deriveCurrentIndex(queue, queueItemId) {
|
|
|
995
996
|
const index = queue.findIndex((entry) => entry.queueItemId === queueItemId);
|
|
996
997
|
return index < 0 ? null : index;
|
|
997
998
|
}
|
|
999
|
+
function synchronizeActiveContext(context, queue, currentQueueItemId) {
|
|
1000
|
+
if (context === null) {
|
|
1001
|
+
return null;
|
|
1002
|
+
}
|
|
1003
|
+
return Object.freeze({
|
|
1004
|
+
...context,
|
|
1005
|
+
queue,
|
|
1006
|
+
currentQueueItemId
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
998
1009
|
function createPlayerSnapshot(previous, patch) {
|
|
999
1010
|
const queue = patch.queue === void 0 ? previous.queue : freezeQueue(patch.queue);
|
|
1000
1011
|
const currentQueueItemId = patch.currentQueueItemId === void 0 ? previous.currentQueueItemId : patch.currentQueueItemId;
|
|
1001
1012
|
const currentQueueIndex = deriveCurrentIndex(queue, currentQueueItemId);
|
|
1002
1013
|
const repeatMode = patch.repeatMode ?? previous.repeatMode;
|
|
1003
1014
|
const currentItem = patch.currentItem === void 0 ? previous.currentItem : patch.currentItem;
|
|
1015
|
+
const activeContext = synchronizeActiveContext(
|
|
1016
|
+
patch.activeContext === void 0 ? previous.activeContext : patch.activeContext,
|
|
1017
|
+
queue,
|
|
1018
|
+
currentQueueItemId
|
|
1019
|
+
);
|
|
1004
1020
|
return Object.freeze({
|
|
1005
1021
|
...previous,
|
|
1006
1022
|
...patch,
|
|
1007
1023
|
queue,
|
|
1024
|
+
activeContext,
|
|
1008
1025
|
currentQueueItemId,
|
|
1009
1026
|
currentQueueIndex,
|
|
1010
1027
|
canGoPrevious: patch.canGoPrevious ?? currentItem !== null,
|
|
@@ -1065,6 +1082,9 @@ function clampVolume2(value) {
|
|
|
1065
1082
|
}
|
|
1066
1083
|
return Math.min(Math.max(value, 0), 1);
|
|
1067
1084
|
}
|
|
1085
|
+
function sourcesMatch(left, right) {
|
|
1086
|
+
return left.url === right.url && left.mimeType === right.mimeType;
|
|
1087
|
+
}
|
|
1068
1088
|
var CorePlayerStore = class {
|
|
1069
1089
|
commands;
|
|
1070
1090
|
experience;
|
|
@@ -1117,6 +1137,10 @@ var CorePlayerStore = class {
|
|
|
1117
1137
|
const commands = {
|
|
1118
1138
|
load: (item) => this.#load(item),
|
|
1119
1139
|
setQueue: (queue, commandOptions) => this.#setQueue(queue, commandOptions),
|
|
1140
|
+
activateContext: (commandOptions) => this.#activateContext(commandOptions),
|
|
1141
|
+
appendToManualHistory: (contextId, item) => {
|
|
1142
|
+
this.#appendToManualHistory(contextId, item);
|
|
1143
|
+
},
|
|
1120
1144
|
play: () => this.#play(),
|
|
1121
1145
|
pause: (commandOptions) => this.#pause(commandOptions),
|
|
1122
1146
|
stop: (commandOptions) => this.#stop(commandOptions),
|
|
@@ -1279,7 +1303,7 @@ var CorePlayerStore = class {
|
|
|
1279
1303
|
async #load(item) {
|
|
1280
1304
|
return this.#setQueue([createLoadedQueueItem(item)]);
|
|
1281
1305
|
}
|
|
1282
|
-
async #setQueue(queue, options = {}) {
|
|
1306
|
+
async #setQueue(queue, options = {}, activeContext) {
|
|
1283
1307
|
if (this.#destroyed) {
|
|
1284
1308
|
return failed(DESTROYED_ERROR);
|
|
1285
1309
|
}
|
|
@@ -1291,15 +1315,23 @@ var CorePlayerStore = class {
|
|
|
1291
1315
|
return OK_RESULT;
|
|
1292
1316
|
}
|
|
1293
1317
|
const normalizedQueue = freezeQueue(queue);
|
|
1294
|
-
const
|
|
1318
|
+
const currentQueueItemId = this.#state.currentQueueItemId;
|
|
1319
|
+
const currentStillExists = currentQueueItemId !== null && findQueueIndex(normalizedQueue, currentQueueItemId) !== null;
|
|
1320
|
+
const startQueueItemId = options.startQueueItemId ?? (currentStillExists ? currentQueueItemId : normalizedQueue[0]?.queueItemId);
|
|
1295
1321
|
const startIndex = startQueueItemId === void 0 ? null : findQueueIndex(normalizedQueue, startQueueItemId);
|
|
1296
1322
|
if (startIndex === null) {
|
|
1297
1323
|
return failed(INVALID_QUEUE_ERROR);
|
|
1298
1324
|
}
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1325
|
+
const selected = normalizedQueue[startIndex];
|
|
1326
|
+
if (selected === void 0) {
|
|
1327
|
+
return failed(INVALID_QUEUE_ERROR);
|
|
1328
|
+
}
|
|
1329
|
+
const preservePlayback = options.reload !== true && currentQueueItemId === selected.queueItemId && this.#state.currentItem !== null && sourcesMatch(this.#state.currentItem.source, selected.item.source);
|
|
1330
|
+
const targetContext = activeContext ?? this.#state.activeContext;
|
|
1331
|
+
const manualHistory = targetContext?.mode === "manual-history";
|
|
1332
|
+
const shuffleEnabled = manualHistory ? false : this.#state.shuffleEnabled;
|
|
1333
|
+
const repeatMode = manualHistory && this.#state.repeatMode === "all" ? "off" : this.#state.repeatMode;
|
|
1334
|
+
const playbackQueue = shuffleEnabled && startQueueItemId !== void 0 ? shuffleQueueAroundCurrent(
|
|
1303
1335
|
normalizedQueue,
|
|
1304
1336
|
startQueueItemId,
|
|
1305
1337
|
this.#random
|
|
@@ -1307,18 +1339,97 @@ var CorePlayerStore = class {
|
|
|
1307
1339
|
this.#playbackOrderQueueItemIds = Object.freeze(
|
|
1308
1340
|
playbackQueue.map((entry) => entry.queueItemId)
|
|
1309
1341
|
);
|
|
1310
|
-
this.#playbackOrderCursor =
|
|
1342
|
+
this.#playbackOrderCursor = shuffleEnabled ? 0 : startIndex;
|
|
1311
1343
|
this.#setState({
|
|
1312
1344
|
queue: normalizedQueue,
|
|
1313
|
-
|
|
1345
|
+
...activeContext === void 0 ? {} : { activeContext },
|
|
1346
|
+
currentItem: preservePlayback ? selected.item : this.#state.currentItem,
|
|
1347
|
+
currentItemId: preservePlayback ? selected.item.id : this.#state.currentItemId,
|
|
1348
|
+
shuffleEnabled,
|
|
1349
|
+
repeatMode,
|
|
1314
1350
|
error: null
|
|
1315
1351
|
});
|
|
1352
|
+
if (preservePlayback) {
|
|
1353
|
+
if (options.autoplay === true && this.#state.status !== "playing") {
|
|
1354
|
+
return this.#play();
|
|
1355
|
+
}
|
|
1356
|
+
return OK_RESULT;
|
|
1357
|
+
}
|
|
1358
|
+
const version = this.#beginCommand(
|
|
1359
|
+
options.autoplay === true ? "playing" : "paused"
|
|
1360
|
+
);
|
|
1316
1361
|
return this.#selectQueueIndex(
|
|
1317
1362
|
version,
|
|
1318
1363
|
startIndex,
|
|
1319
1364
|
options.autoplay === true
|
|
1320
1365
|
);
|
|
1321
1366
|
}
|
|
1367
|
+
async #activateContext(options) {
|
|
1368
|
+
if (this.#destroyed) {
|
|
1369
|
+
return failed(DESTROYED_ERROR);
|
|
1370
|
+
}
|
|
1371
|
+
if (options.contextId.trim().length === 0) {
|
|
1372
|
+
return failed(INVALID_QUEUE_ERROR);
|
|
1373
|
+
}
|
|
1374
|
+
const suppliedQueue = options.queue ?? (this.#state.activeContext?.id === options.contextId ? this.#state.queue : void 0);
|
|
1375
|
+
if (suppliedQueue === void 0 || !hasUniqueQueueItemIds(suppliedQueue)) {
|
|
1376
|
+
return failed(INVALID_QUEUE_ERROR);
|
|
1377
|
+
}
|
|
1378
|
+
const startIndex = findQueueIndex(
|
|
1379
|
+
suppliedQueue,
|
|
1380
|
+
options.startQueueItemId
|
|
1381
|
+
);
|
|
1382
|
+
if (startIndex === null) {
|
|
1383
|
+
return failed(INVALID_QUEUE_ERROR);
|
|
1384
|
+
}
|
|
1385
|
+
const startItem = suppliedQueue[startIndex];
|
|
1386
|
+
if (startItem === void 0) {
|
|
1387
|
+
return failed(INVALID_QUEUE_ERROR);
|
|
1388
|
+
}
|
|
1389
|
+
let queue;
|
|
1390
|
+
if (options.mode === "manual-history") {
|
|
1391
|
+
const sameManualContext = this.#state.activeContext?.id === options.contextId && this.#state.activeContext.mode === "manual-history";
|
|
1392
|
+
const history = sameManualContext ? [...this.#state.queue] : [];
|
|
1393
|
+
const existingIndex = findQueueIndex(history, startItem.queueItemId);
|
|
1394
|
+
if (existingIndex === null) {
|
|
1395
|
+
history.push(startItem);
|
|
1396
|
+
} else {
|
|
1397
|
+
history[existingIndex] = startItem;
|
|
1398
|
+
}
|
|
1399
|
+
queue = freezeQueue(history);
|
|
1400
|
+
} else {
|
|
1401
|
+
queue = freezeQueue(suppliedQueue);
|
|
1402
|
+
}
|
|
1403
|
+
const previousContext = this.#state.activeContext;
|
|
1404
|
+
const context = Object.freeze({
|
|
1405
|
+
id: options.contextId,
|
|
1406
|
+
mode: options.mode,
|
|
1407
|
+
...options.label === void 0 && previousContext?.id === options.contextId ? previousContext.label === void 0 ? {} : { label: previousContext.label } : options.label === void 0 ? {} : { label: options.label },
|
|
1408
|
+
queue,
|
|
1409
|
+
currentQueueItemId: options.startQueueItemId
|
|
1410
|
+
});
|
|
1411
|
+
return this.#setQueue(
|
|
1412
|
+
queue,
|
|
1413
|
+
{
|
|
1414
|
+
startQueueItemId: options.startQueueItemId,
|
|
1415
|
+
...options.autoplay === void 0 ? {} : { autoplay: options.autoplay },
|
|
1416
|
+
...options.reload === void 0 ? {} : { reload: options.reload }
|
|
1417
|
+
},
|
|
1418
|
+
context
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
#appendToManualHistory(contextId, item) {
|
|
1422
|
+
const context = this.#state.activeContext;
|
|
1423
|
+
if (this.#destroyed || context?.id !== contextId || context.mode !== "manual-history" || findQueueIndex(this.#state.queue, item.queueItemId) !== null) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1426
|
+
const queue = freezeQueue([...this.#state.queue, item]);
|
|
1427
|
+
this.#playbackOrderQueueItemIds = Object.freeze(
|
|
1428
|
+
queue.map((entry) => entry.queueItemId)
|
|
1429
|
+
);
|
|
1430
|
+
this.#playbackOrderCursor = this.#state.currentQueueItemId === null ? -1 : findQueueIndex(queue, this.#state.currentQueueItemId) ?? -1;
|
|
1431
|
+
this.#setState({ queue });
|
|
1432
|
+
}
|
|
1322
1433
|
async #selectQueueIndex(version, index, autoplay) {
|
|
1323
1434
|
const selected = this.#state.queue[index];
|
|
1324
1435
|
if (selected === void 0) {
|
|
@@ -1591,7 +1702,7 @@ var CorePlayerStore = class {
|
|
|
1591
1702
|
this.#setState({ muted });
|
|
1592
1703
|
}
|
|
1593
1704
|
#setShuffle(enabled) {
|
|
1594
|
-
if (this.#destroyed || enabled === this.#state.shuffleEnabled) {
|
|
1705
|
+
if (this.#destroyed || enabled && this.#state.activeContext?.mode === "manual-history" || enabled === this.#state.shuffleEnabled) {
|
|
1595
1706
|
return;
|
|
1596
1707
|
}
|
|
1597
1708
|
const currentQueueItemId = this.#state.currentQueueItemId;
|
|
@@ -1616,7 +1727,9 @@ var CorePlayerStore = class {
|
|
|
1616
1727
|
if (this.#destroyed) {
|
|
1617
1728
|
return;
|
|
1618
1729
|
}
|
|
1619
|
-
this.#setState({
|
|
1730
|
+
this.#setState({
|
|
1731
|
+
repeatMode: this.#state.activeContext?.mode === "manual-history" && mode === "all" ? "off" : mode
|
|
1732
|
+
});
|
|
1620
1733
|
}
|
|
1621
1734
|
async #next() {
|
|
1622
1735
|
if (this.#destroyed) {
|
|
@@ -1715,6 +1828,7 @@ var CorePlayerStore = class {
|
|
|
1715
1828
|
currentTimeSec: 0,
|
|
1716
1829
|
durationSec: null,
|
|
1717
1830
|
queue: Object.freeze([]),
|
|
1831
|
+
activeContext: null,
|
|
1718
1832
|
canSeek: false,
|
|
1719
1833
|
needsUserGesture: false,
|
|
1720
1834
|
error: null
|
|
@@ -1884,6 +1998,14 @@ var CorePlayerStore = class {
|
|
|
1884
1998
|
);
|
|
1885
1999
|
return;
|
|
1886
2000
|
}
|
|
2001
|
+
if (this.#state.activeContext?.mode === "manual-history") {
|
|
2002
|
+
this.#desiredPlayback = "paused";
|
|
2003
|
+
this.#setState({
|
|
2004
|
+
status: "ended",
|
|
2005
|
+
currentTimeSec: readFiniteDuration(this.#media) ?? readFiniteCurrentTime(this.#media)
|
|
2006
|
+
});
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
1887
2009
|
const nextPlaybackIndex = this.#getNextPlaybackIndex(
|
|
1888
2010
|
currentQueueItemId
|
|
1889
2011
|
);
|
|
@@ -1985,6 +2107,17 @@ function createGestureAwareCommands(commands, gain, activationOptions = {}) {
|
|
|
1985
2107
|
}
|
|
1986
2108
|
return commands.setQueue(queue, commandOptions);
|
|
1987
2109
|
},
|
|
2110
|
+
activateContext(commandOptions) {
|
|
2111
|
+
reportCommand(activationOptions, "activateContext");
|
|
2112
|
+
if (commandOptions.autoplay === true) {
|
|
2113
|
+
activate(gain, activationOptions);
|
|
2114
|
+
}
|
|
2115
|
+
return commands.activateContext(commandOptions);
|
|
2116
|
+
},
|
|
2117
|
+
appendToManualHistory(contextId, item) {
|
|
2118
|
+
reportCommand(activationOptions, "appendToManualHistory");
|
|
2119
|
+
commands.appendToManualHistory(contextId, item);
|
|
2120
|
+
},
|
|
1988
2121
|
play() {
|
|
1989
2122
|
reportCommand(activationOptions, "play");
|
|
1990
2123
|
activate(gain, activationOptions);
|
|
@@ -2387,7 +2520,583 @@ function usePlayer() {
|
|
|
2387
2520
|
mediaSessionActionsEnabled: context.mediaSessionActionsEnabled
|
|
2388
2521
|
};
|
|
2389
2522
|
}
|
|
2523
|
+
function deriveBoundPlayerViewState(playerState, contextId, queueItem) {
|
|
2524
|
+
const isActive = playerState.activeContext?.id === contextId && playerState.currentQueueItemId === queueItem.queueItemId;
|
|
2525
|
+
return Object.freeze({
|
|
2526
|
+
queueItemId: queueItem.queueItemId,
|
|
2527
|
+
item: isActive ? playerState.currentItem ?? queueItem.item : queueItem.item,
|
|
2528
|
+
isActive,
|
|
2529
|
+
status: isActive ? playerState.status : "paused",
|
|
2530
|
+
currentTimeSec: isActive ? playerState.currentTimeSec : 0,
|
|
2531
|
+
durationSec: isActive ? playerState.durationSec : queueItem.item.durationHintSec ?? null,
|
|
2532
|
+
canSeek: isActive && playerState.canSeek,
|
|
2533
|
+
isPlaying: isActive && playerState.status === "playing"
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2536
|
+
function useBoundPlayer({
|
|
2537
|
+
context,
|
|
2538
|
+
queueItem
|
|
2539
|
+
}) {
|
|
2540
|
+
const player = usePlayer();
|
|
2541
|
+
const state = useMemo(
|
|
2542
|
+
() => deriveBoundPlayerViewState(player.state, context.id, queueItem),
|
|
2543
|
+
[context.id, player.state, queueItem]
|
|
2544
|
+
);
|
|
2545
|
+
const commands = useMemo(() => {
|
|
2546
|
+
const play = () => player.commands.activateContext({
|
|
2547
|
+
contextId: context.id,
|
|
2548
|
+
mode: context.mode,
|
|
2549
|
+
...context.label === void 0 ? {} : { label: context.label },
|
|
2550
|
+
queue: context.mode === "manual-history" ? [queueItem] : context.queue,
|
|
2551
|
+
startQueueItemId: queueItem.queueItemId,
|
|
2552
|
+
autoplay: true
|
|
2553
|
+
});
|
|
2554
|
+
return Object.freeze({
|
|
2555
|
+
play,
|
|
2556
|
+
togglePlayback() {
|
|
2557
|
+
if (player.state.activeContext?.id === context.id && player.state.currentQueueItemId === queueItem.queueItemId) {
|
|
2558
|
+
return player.commands.togglePlayback();
|
|
2559
|
+
}
|
|
2560
|
+
return play();
|
|
2561
|
+
},
|
|
2562
|
+
seekTo(seconds) {
|
|
2563
|
+
if (player.state.activeContext?.id === context.id && player.state.currentQueueItemId === queueItem.queueItemId && player.state.canSeek) {
|
|
2564
|
+
player.commands.seekTo(seconds);
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
});
|
|
2568
|
+
}, [context, player.commands, player.state, queueItem]);
|
|
2569
|
+
return { state, commands };
|
|
2570
|
+
}
|
|
2571
|
+
function IconFrame({
|
|
2572
|
+
children,
|
|
2573
|
+
size = 20,
|
|
2574
|
+
...props
|
|
2575
|
+
}) {
|
|
2576
|
+
return /* @__PURE__ */ jsx(
|
|
2577
|
+
"svg",
|
|
2578
|
+
{
|
|
2579
|
+
"aria-hidden": "true",
|
|
2580
|
+
focusable: "false",
|
|
2581
|
+
viewBox: "0 0 24 24",
|
|
2582
|
+
width: size,
|
|
2583
|
+
height: size,
|
|
2584
|
+
fill: "currentColor",
|
|
2585
|
+
...props,
|
|
2586
|
+
children
|
|
2587
|
+
}
|
|
2588
|
+
);
|
|
2589
|
+
}
|
|
2590
|
+
function PlayIcon(props) {
|
|
2591
|
+
return /* @__PURE__ */ jsx(IconFrame, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M7 4.8c0-1.05 1.16-1.68 2.04-1.1l11 7.2a1.3 1.3 0 0 1 0 2.2l-11 7.2A1.31 1.31 0 0 1 7 19.2V4.8Z" }) });
|
|
2592
|
+
}
|
|
2593
|
+
function PauseIcon(props) {
|
|
2594
|
+
return /* @__PURE__ */ jsxs(IconFrame, { ...props, children: [
|
|
2595
|
+
/* @__PURE__ */ jsx("rect", { x: "5", y: "4", width: "5", height: "16", rx: "0.8" }),
|
|
2596
|
+
/* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "5", height: "16", rx: "0.8" })
|
|
2597
|
+
] });
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
// src/ui/player-utils.ts
|
|
2601
|
+
function clamp(value, min, max) {
|
|
2602
|
+
return Math.min(Math.max(value, min), max);
|
|
2603
|
+
}
|
|
2604
|
+
function formatTime(seconds) {
|
|
2605
|
+
if (seconds === null || !Number.isFinite(seconds) || seconds < 0) {
|
|
2606
|
+
return "--:--";
|
|
2607
|
+
}
|
|
2608
|
+
const wholeSeconds = Math.floor(seconds);
|
|
2609
|
+
const hours = Math.floor(wholeSeconds / 3600);
|
|
2610
|
+
const minutes = Math.floor(wholeSeconds % 3600 / 60);
|
|
2611
|
+
const remainder = wholeSeconds % 60;
|
|
2612
|
+
if (hours > 0) {
|
|
2613
|
+
return `${String(hours)}:${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}`;
|
|
2614
|
+
}
|
|
2615
|
+
return `${String(minutes).padStart(2, "0")}:${String(remainder).padStart(2, "0")}`;
|
|
2616
|
+
}
|
|
2617
|
+
function formatTimeAria(seconds) {
|
|
2618
|
+
const safeSeconds = Math.max(0, Math.floor(seconds));
|
|
2619
|
+
const hours = Math.floor(safeSeconds / 3600);
|
|
2620
|
+
const minutes = Math.floor(safeSeconds % 3600 / 60);
|
|
2621
|
+
const remainder = safeSeconds % 60;
|
|
2622
|
+
const parts = [
|
|
2623
|
+
hours > 0 ? `${String(hours)} hour${hours === 1 ? "" : "s"}` : "",
|
|
2624
|
+
minutes > 0 ? `${String(minutes)} minute${minutes === 1 ? "" : "s"}` : "",
|
|
2625
|
+
`${String(remainder)} second${remainder === 1 ? "" : "s"}`
|
|
2626
|
+
].filter(Boolean);
|
|
2627
|
+
return parts.join(" ");
|
|
2628
|
+
}
|
|
2629
|
+
function PlayerSurface({
|
|
2630
|
+
appearance,
|
|
2631
|
+
children,
|
|
2632
|
+
className,
|
|
2633
|
+
label
|
|
2634
|
+
}) {
|
|
2635
|
+
return /* @__PURE__ */ jsx(
|
|
2636
|
+
"section",
|
|
2637
|
+
{
|
|
2638
|
+
"aria-label": label,
|
|
2639
|
+
className: ["player-surface", className].filter(Boolean).join(" "),
|
|
2640
|
+
"data-appearance": appearance,
|
|
2641
|
+
children
|
|
2642
|
+
}
|
|
2643
|
+
);
|
|
2644
|
+
}
|
|
2645
|
+
function Artwork({ className, item }) {
|
|
2646
|
+
const classes = ["player-artwork", className].filter(Boolean).join(" ");
|
|
2647
|
+
if (item?.artwork !== void 0) {
|
|
2648
|
+
return /* @__PURE__ */ jsx("span", { className: `${classes} player-artwork--image`, children: /* @__PURE__ */ jsx(
|
|
2649
|
+
"img",
|
|
2650
|
+
{
|
|
2651
|
+
alt: item.artwork.alt,
|
|
2652
|
+
className: "player-artwork__image",
|
|
2653
|
+
decoding: "async",
|
|
2654
|
+
src: item.artwork.url
|
|
2655
|
+
}
|
|
2656
|
+
) });
|
|
2657
|
+
}
|
|
2658
|
+
return /* @__PURE__ */ jsx(
|
|
2659
|
+
"div",
|
|
2660
|
+
{
|
|
2661
|
+
"aria-label": "Artwork unavailable",
|
|
2662
|
+
className: `${classes} player-artwork--fallback`,
|
|
2663
|
+
role: "img",
|
|
2664
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true" })
|
|
2665
|
+
}
|
|
2666
|
+
);
|
|
2667
|
+
}
|
|
2668
|
+
function ScrollingTitle({
|
|
2669
|
+
enabled,
|
|
2670
|
+
title
|
|
2671
|
+
}) {
|
|
2672
|
+
const containsJapanese = /[\u3040-\u30ff\u3400-\u9fff]/u.test(title);
|
|
2673
|
+
const viewportRef = useRef(null);
|
|
2674
|
+
const contentRef = useRef(null);
|
|
2675
|
+
const [marquee, setMarquee] = useState({
|
|
2676
|
+
distance: 0,
|
|
2677
|
+
duration: 10,
|
|
2678
|
+
overflow: false
|
|
2679
|
+
});
|
|
2680
|
+
useEffect(() => {
|
|
2681
|
+
const viewport = viewportRef.current;
|
|
2682
|
+
const content = contentRef.current;
|
|
2683
|
+
if (viewport === null || content === null) {
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
const viewportElement = viewport;
|
|
2687
|
+
const contentElement = content;
|
|
2688
|
+
function measure() {
|
|
2689
|
+
const viewportWidth = Math.max(
|
|
2690
|
+
viewportElement.getBoundingClientRect().width,
|
|
2691
|
+
viewportElement.clientWidth
|
|
2692
|
+
);
|
|
2693
|
+
const contentWidth = Math.max(
|
|
2694
|
+
contentElement.getBoundingClientRect().width,
|
|
2695
|
+
contentElement.scrollWidth
|
|
2696
|
+
);
|
|
2697
|
+
const overflow = contentWidth - viewportWidth > 1;
|
|
2698
|
+
const distance = enabled ? contentWidth + 12 : 0;
|
|
2699
|
+
setMarquee({
|
|
2700
|
+
distance,
|
|
2701
|
+
duration: Math.max(10, distance / 22 + 4),
|
|
2702
|
+
overflow
|
|
2703
|
+
});
|
|
2704
|
+
}
|
|
2705
|
+
measure();
|
|
2706
|
+
if (typeof ResizeObserver === "undefined") {
|
|
2707
|
+
window.addEventListener("resize", measure);
|
|
2708
|
+
return () => {
|
|
2709
|
+
window.removeEventListener("resize", measure);
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
const observer = new ResizeObserver(measure);
|
|
2713
|
+
observer.observe(viewportElement);
|
|
2714
|
+
observer.observe(contentElement);
|
|
2715
|
+
return () => {
|
|
2716
|
+
observer.disconnect();
|
|
2717
|
+
};
|
|
2718
|
+
}, [enabled, title]);
|
|
2719
|
+
const style = {
|
|
2720
|
+
"--player-title-scroll-offset": `${String(-marquee.distance)}px`,
|
|
2721
|
+
"--player-title-scroll-duration": `${String(marquee.duration)}s`
|
|
2722
|
+
};
|
|
2723
|
+
return /* @__PURE__ */ jsx(
|
|
2724
|
+
"strong",
|
|
2725
|
+
{
|
|
2726
|
+
className: "player-title",
|
|
2727
|
+
"data-overflow": marquee.overflow ? "true" : "false",
|
|
2728
|
+
"data-scroll": enabled ? "true" : "false",
|
|
2729
|
+
"data-script": containsJapanese ? "japanese" : "latin",
|
|
2730
|
+
ref: viewportRef,
|
|
2731
|
+
style,
|
|
2732
|
+
children: /* @__PURE__ */ jsx("span", { className: "player-title__text", ref: contentRef, children: title })
|
|
2733
|
+
}
|
|
2734
|
+
);
|
|
2735
|
+
}
|
|
2736
|
+
function TrackMetadata({
|
|
2737
|
+
className,
|
|
2738
|
+
item,
|
|
2739
|
+
scrollTitle = false,
|
|
2740
|
+
status
|
|
2741
|
+
}) {
|
|
2742
|
+
return /* @__PURE__ */ jsxs(
|
|
2743
|
+
"div",
|
|
2744
|
+
{
|
|
2745
|
+
className: ["player-metadata", className].filter(Boolean).join(" "),
|
|
2746
|
+
children: [
|
|
2747
|
+
status === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "player-kicker", children: status }),
|
|
2748
|
+
/* @__PURE__ */ jsx(
|
|
2749
|
+
ScrollingTitle,
|
|
2750
|
+
{
|
|
2751
|
+
enabled: item !== null && scrollTitle,
|
|
2752
|
+
title: item?.title ?? "No media selected"
|
|
2753
|
+
},
|
|
2754
|
+
item?.title ?? "No media selected"
|
|
2755
|
+
),
|
|
2756
|
+
/* @__PURE__ */ jsx("span", { className: "player-creator", children: item === null ? "Select media to begin" : item.creatorName ?? "Artist unavailable" }),
|
|
2757
|
+
item?.collectionTitle === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "player-collection", children: item.collectionTitle })
|
|
2758
|
+
]
|
|
2759
|
+
}
|
|
2760
|
+
);
|
|
2761
|
+
}
|
|
2762
|
+
function TimeReadout({
|
|
2763
|
+
className,
|
|
2764
|
+
currentTimeSec,
|
|
2765
|
+
durationSec
|
|
2766
|
+
}) {
|
|
2767
|
+
return /* @__PURE__ */ jsxs(
|
|
2768
|
+
"div",
|
|
2769
|
+
{
|
|
2770
|
+
"aria-label": `${formatTime(currentTimeSec)} of ${formatTime(durationSec)}`,
|
|
2771
|
+
className: ["player-time", className].filter(Boolean).join(" "),
|
|
2772
|
+
children: [
|
|
2773
|
+
/* @__PURE__ */ jsx("time", { children: formatTime(currentTimeSec) }),
|
|
2774
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "/" }),
|
|
2775
|
+
/* @__PURE__ */ jsx("time", { children: formatTime(durationSec) })
|
|
2776
|
+
]
|
|
2777
|
+
}
|
|
2778
|
+
);
|
|
2779
|
+
}
|
|
2780
|
+
function IconButton({
|
|
2781
|
+
children,
|
|
2782
|
+
className,
|
|
2783
|
+
disabled = false,
|
|
2784
|
+
label,
|
|
2785
|
+
onClick,
|
|
2786
|
+
pressed
|
|
2787
|
+
}) {
|
|
2788
|
+
return /* @__PURE__ */ jsx(
|
|
2789
|
+
"button",
|
|
2790
|
+
{
|
|
2791
|
+
"aria-label": label,
|
|
2792
|
+
...pressed === void 0 ? {} : { "aria-pressed": pressed },
|
|
2793
|
+
className: ["player-icon-button", className].filter(Boolean).join(" "),
|
|
2794
|
+
disabled,
|
|
2795
|
+
onClick,
|
|
2796
|
+
title: label,
|
|
2797
|
+
type: "button",
|
|
2798
|
+
children
|
|
2799
|
+
}
|
|
2800
|
+
);
|
|
2801
|
+
}
|
|
2802
|
+
function SeekBar({
|
|
2803
|
+
canSeek,
|
|
2804
|
+
className,
|
|
2805
|
+
commitMode,
|
|
2806
|
+
currentTimeSec,
|
|
2807
|
+
durationSec,
|
|
2808
|
+
label = "Seek",
|
|
2809
|
+
onSeek,
|
|
2810
|
+
status
|
|
2811
|
+
}) {
|
|
2812
|
+
const duration = durationSec !== null && Number.isFinite(durationSec) && durationSec > 0 ? durationSec : 0;
|
|
2813
|
+
const disabled = !canSeek || duration === 0 || status === "loading";
|
|
2814
|
+
const safeCurrentTime = clamp(currentTimeSec, 0, duration);
|
|
2815
|
+
const [previewTime, setPreviewTime] = useState(safeCurrentTime);
|
|
2816
|
+
const previewProgress = duration === 0 ? 0 : clamp(previewTime / duration, 0, 1) * 100;
|
|
2817
|
+
const isAdjusting = useRef(false);
|
|
2818
|
+
const lastCommitted = useRef(null);
|
|
2819
|
+
useEffect(() => {
|
|
2820
|
+
if (!isAdjusting.current) {
|
|
2821
|
+
setPreviewTime(safeCurrentTime);
|
|
2822
|
+
}
|
|
2823
|
+
}, [safeCurrentTime]);
|
|
2824
|
+
function updatePreview(value) {
|
|
2825
|
+
const nextValue = clamp(value, 0, duration);
|
|
2826
|
+
isAdjusting.current = true;
|
|
2827
|
+
setPreviewTime(nextValue);
|
|
2828
|
+
if (commitMode === "live") {
|
|
2829
|
+
onSeek(nextValue);
|
|
2830
|
+
lastCommitted.current = nextValue;
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
function commitPreview(value = previewTime) {
|
|
2834
|
+
const nextValue = clamp(value, 0, duration);
|
|
2835
|
+
if (disabled || !isAdjusting.current || commitMode === "live" && lastCommitted.current === nextValue) {
|
|
2836
|
+
isAdjusting.current = false;
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
onSeek(nextValue);
|
|
2840
|
+
lastCommitted.current = nextValue;
|
|
2841
|
+
isAdjusting.current = false;
|
|
2842
|
+
}
|
|
2843
|
+
function cancelPreview() {
|
|
2844
|
+
isAdjusting.current = false;
|
|
2845
|
+
lastCommitted.current = null;
|
|
2846
|
+
setPreviewTime(safeCurrentTime);
|
|
2847
|
+
}
|
|
2848
|
+
return /* @__PURE__ */ jsxs(
|
|
2849
|
+
"label",
|
|
2850
|
+
{
|
|
2851
|
+
className: ["player-seek", className].filter(Boolean).join(" "),
|
|
2852
|
+
"data-disabled": disabled ? "true" : "false",
|
|
2853
|
+
children: [
|
|
2854
|
+
/* @__PURE__ */ jsx("span", { className: "player-visually-hidden", children: label }),
|
|
2855
|
+
/* @__PURE__ */ jsx(
|
|
2856
|
+
"span",
|
|
2857
|
+
{
|
|
2858
|
+
"aria-hidden": "true",
|
|
2859
|
+
className: "player-seek__progress",
|
|
2860
|
+
style: { width: `${String(disabled ? 0 : previewProgress)}%` }
|
|
2861
|
+
}
|
|
2862
|
+
),
|
|
2863
|
+
/* @__PURE__ */ jsx(
|
|
2864
|
+
"input",
|
|
2865
|
+
{
|
|
2866
|
+
"aria-label": label,
|
|
2867
|
+
"aria-valuetext": formatTimeAria(previewTime),
|
|
2868
|
+
disabled,
|
|
2869
|
+
max: duration || 1,
|
|
2870
|
+
min: 0,
|
|
2871
|
+
onBlur: (event) => {
|
|
2872
|
+
commitPreview(Number(event.currentTarget.value));
|
|
2873
|
+
},
|
|
2874
|
+
onChange: (event) => {
|
|
2875
|
+
updatePreview(Number(event.currentTarget.value));
|
|
2876
|
+
},
|
|
2877
|
+
onKeyUp: (event) => {
|
|
2878
|
+
commitPreview(Number(event.currentTarget.value));
|
|
2879
|
+
},
|
|
2880
|
+
onPointerDown: () => {
|
|
2881
|
+
isAdjusting.current = true;
|
|
2882
|
+
},
|
|
2883
|
+
onPointerCancel: cancelPreview,
|
|
2884
|
+
onPointerUp: (event) => {
|
|
2885
|
+
commitPreview(Number(event.currentTarget.value));
|
|
2886
|
+
},
|
|
2887
|
+
step: 0.1,
|
|
2888
|
+
type: "range",
|
|
2889
|
+
value: disabled ? 0 : previewTime
|
|
2890
|
+
}
|
|
2891
|
+
)
|
|
2892
|
+
]
|
|
2893
|
+
}
|
|
2894
|
+
);
|
|
2895
|
+
}
|
|
2896
|
+
var FALLBACK_PEAKS = [
|
|
2897
|
+
0.16,
|
|
2898
|
+
0.24,
|
|
2899
|
+
0.42,
|
|
2900
|
+
0.3,
|
|
2901
|
+
0.58,
|
|
2902
|
+
0.76,
|
|
2903
|
+
0.48,
|
|
2904
|
+
0.34,
|
|
2905
|
+
0.66,
|
|
2906
|
+
0.88,
|
|
2907
|
+
0.62,
|
|
2908
|
+
0.4,
|
|
2909
|
+
0.52,
|
|
2910
|
+
0.72,
|
|
2911
|
+
0.44,
|
|
2912
|
+
0.28,
|
|
2913
|
+
0.56,
|
|
2914
|
+
0.82,
|
|
2915
|
+
0.68,
|
|
2916
|
+
0.38,
|
|
2917
|
+
0.24,
|
|
2918
|
+
0.46,
|
|
2919
|
+
0.32,
|
|
2920
|
+
0.18
|
|
2921
|
+
];
|
|
2922
|
+
var BAR_COUNT = 512;
|
|
2923
|
+
var VIEWBOX_WIDTH = BAR_COUNT;
|
|
2924
|
+
function createWaveformBars(peaks) {
|
|
2925
|
+
const source = peaks.length > 1 ? peaks : FALLBACK_PEAKS;
|
|
2926
|
+
return Array.from({ length: BAR_COUNT }, (_, index) => {
|
|
2927
|
+
const sourcePosition = index / Math.max(BAR_COUNT - 1, 1) * (source.length - 1);
|
|
2928
|
+
const leftIndex = Math.floor(sourcePosition);
|
|
2929
|
+
const rightIndex = Math.min(leftIndex + 1, source.length - 1);
|
|
2930
|
+
const mix = sourcePosition - leftIndex;
|
|
2931
|
+
const leftPeak = Math.abs(source[leftIndex] ?? 0);
|
|
2932
|
+
const rightPeak = Math.abs(source[rightIndex] ?? leftPeak);
|
|
2933
|
+
const interpolated = leftPeak + (rightPeak - leftPeak) * mix;
|
|
2934
|
+
if (source.length >= BAR_COUNT) {
|
|
2935
|
+
return clamp(Math.pow(interpolated, 1.18), 0.04, 1);
|
|
2936
|
+
}
|
|
2937
|
+
const noiseSeed = Math.sin((index + 1) * 12.9898 + source.length * 78.233) * 43758.5453;
|
|
2938
|
+
const noise = noiseSeed - Math.floor(noiseSeed);
|
|
2939
|
+
const fineDetail = 0.76 + noise * 0.34;
|
|
2940
|
+
const transient = noise > 0.975 ? 3.2 : noise > 0.91 ? 1.75 : 1;
|
|
2941
|
+
return clamp(
|
|
2942
|
+
Math.pow(interpolated, 1.22) * fineDetail * transient,
|
|
2943
|
+
0.04,
|
|
2944
|
+
1
|
|
2945
|
+
);
|
|
2946
|
+
});
|
|
2947
|
+
}
|
|
2948
|
+
function Waveform({
|
|
2949
|
+
className,
|
|
2950
|
+
opacity = 1,
|
|
2951
|
+
playedStateEnabled = true,
|
|
2952
|
+
progress = 0,
|
|
2953
|
+
waveform
|
|
2954
|
+
}) {
|
|
2955
|
+
const clipId = useId().replaceAll(":", "");
|
|
2956
|
+
const bars = createWaveformBars(waveform?.peaks ?? FALLBACK_PEAKS);
|
|
2957
|
+
const progressWidth = clamp(progress, 0, 1) * VIEWBOX_WIDTH;
|
|
2958
|
+
const classes = ["player-waveform", className].filter(Boolean).join(" ");
|
|
2959
|
+
const barPath = bars.map((peak, index) => {
|
|
2960
|
+
const halfHeight = peak * 47;
|
|
2961
|
+
const x = index + 0.5;
|
|
2962
|
+
return `M ${String(x)} ${String(50 - halfHeight)} V ${String(
|
|
2963
|
+
50 + halfHeight
|
|
2964
|
+
)}`;
|
|
2965
|
+
}).join(" ");
|
|
2966
|
+
return /* @__PURE__ */ jsxs(
|
|
2967
|
+
"svg",
|
|
2968
|
+
{
|
|
2969
|
+
"aria-hidden": "true",
|
|
2970
|
+
className: classes,
|
|
2971
|
+
focusable: "false",
|
|
2972
|
+
preserveAspectRatio: "none",
|
|
2973
|
+
style: { opacity: clamp(opacity, 0, 1), pointerEvents: "none" },
|
|
2974
|
+
viewBox: `0 0 ${String(VIEWBOX_WIDTH)} 100`,
|
|
2975
|
+
children: [
|
|
2976
|
+
/* @__PURE__ */ jsx("path", { className: "player-waveform__base", d: barPath }),
|
|
2977
|
+
playedStateEnabled ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2978
|
+
/* @__PURE__ */ jsx("clipPath", { id: clipId, children: /* @__PURE__ */ jsx("rect", { width: progressWidth, height: "100" }) }),
|
|
2979
|
+
/* @__PURE__ */ jsx(
|
|
2980
|
+
"path",
|
|
2981
|
+
{
|
|
2982
|
+
className: "player-waveform__played",
|
|
2983
|
+
clipPath: `url(#${clipId})`,
|
|
2984
|
+
d: barPath
|
|
2985
|
+
}
|
|
2986
|
+
)
|
|
2987
|
+
] }) : null
|
|
2988
|
+
]
|
|
2989
|
+
}
|
|
2990
|
+
);
|
|
2991
|
+
}
|
|
2992
|
+
function BoundCompactPlayerView({
|
|
2993
|
+
appearance,
|
|
2994
|
+
className,
|
|
2995
|
+
commands,
|
|
2996
|
+
contextId,
|
|
2997
|
+
contextMode,
|
|
2998
|
+
options,
|
|
2999
|
+
state
|
|
3000
|
+
}) {
|
|
3001
|
+
const progress = state.durationSec === null || state.durationSec <= 0 ? 0 : state.currentTimeSec / state.durationSec;
|
|
3002
|
+
return /* @__PURE__ */ jsx(
|
|
3003
|
+
PlayerSurface,
|
|
3004
|
+
{
|
|
3005
|
+
appearance,
|
|
3006
|
+
className: ["player-bound-compact", className].filter(Boolean).join(" "),
|
|
3007
|
+
label: `Inline player: ${state.item.title}`,
|
|
3008
|
+
children: /* @__PURE__ */ jsxs(
|
|
3009
|
+
"div",
|
|
3010
|
+
{
|
|
3011
|
+
className: "player-bound-compact__main",
|
|
3012
|
+
"data-active": state.isActive ? "true" : "false",
|
|
3013
|
+
"data-playback-context-id": contextId,
|
|
3014
|
+
"data-playback-context-mode": contextMode,
|
|
3015
|
+
"data-queue-item-id": state.queueItemId,
|
|
3016
|
+
children: [
|
|
3017
|
+
/* @__PURE__ */ jsx(
|
|
3018
|
+
IconButton,
|
|
3019
|
+
{
|
|
3020
|
+
className: "player-play-button",
|
|
3021
|
+
label: state.isPlaying ? "Pause" : "Play",
|
|
3022
|
+
onClick: () => {
|
|
3023
|
+
void commands.togglePlayback();
|
|
3024
|
+
},
|
|
3025
|
+
children: state.isPlaying ? /* @__PURE__ */ jsx(PauseIcon, { size: 22 }) : /* @__PURE__ */ jsx(PlayIcon, { size: 22 })
|
|
3026
|
+
}
|
|
3027
|
+
),
|
|
3028
|
+
/* @__PURE__ */ jsx(
|
|
3029
|
+
Artwork,
|
|
3030
|
+
{
|
|
3031
|
+
className: "player-bound-compact__artwork",
|
|
3032
|
+
item: state.item
|
|
3033
|
+
}
|
|
3034
|
+
),
|
|
3035
|
+
/* @__PURE__ */ jsx(TrackMetadata, { item: state.item, scrollTitle: state.isPlaying }),
|
|
3036
|
+
/* @__PURE__ */ jsxs("div", { className: "player-bound-compact__signal", children: [
|
|
3037
|
+
/* @__PURE__ */ jsx(
|
|
3038
|
+
Waveform,
|
|
3039
|
+
{
|
|
3040
|
+
opacity: options.waveformOpacity,
|
|
3041
|
+
playedStateEnabled: options.waveformPlayedStateEnabled,
|
|
3042
|
+
progress,
|
|
3043
|
+
waveform: state.item.waveform
|
|
3044
|
+
}
|
|
3045
|
+
),
|
|
3046
|
+
/* @__PURE__ */ jsx(
|
|
3047
|
+
TimeReadout,
|
|
3048
|
+
{
|
|
3049
|
+
currentTimeSec: state.currentTimeSec,
|
|
3050
|
+
durationSec: state.durationSec
|
|
3051
|
+
}
|
|
3052
|
+
)
|
|
3053
|
+
] }),
|
|
3054
|
+
/* @__PURE__ */ jsx(
|
|
3055
|
+
SeekBar,
|
|
3056
|
+
{
|
|
3057
|
+
canSeek: state.canSeek,
|
|
3058
|
+
commitMode: options.seekCommitMode,
|
|
3059
|
+
currentTimeSec: state.currentTimeSec,
|
|
3060
|
+
durationSec: state.durationSec,
|
|
3061
|
+
label: `Seek in ${state.item.title}`,
|
|
3062
|
+
onSeek: (seconds) => {
|
|
3063
|
+
commands.seekTo(seconds);
|
|
3064
|
+
},
|
|
3065
|
+
status: state.status
|
|
3066
|
+
}
|
|
3067
|
+
)
|
|
3068
|
+
]
|
|
3069
|
+
}
|
|
3070
|
+
)
|
|
3071
|
+
}
|
|
3072
|
+
);
|
|
3073
|
+
}
|
|
3074
|
+
function BoundCompactPlayer({
|
|
3075
|
+
appearance,
|
|
3076
|
+
className,
|
|
3077
|
+
context,
|
|
3078
|
+
queueItem
|
|
3079
|
+
}) {
|
|
3080
|
+
const bound = useBoundPlayer({ context, queueItem });
|
|
3081
|
+
const player = usePlayer();
|
|
3082
|
+
return /* @__PURE__ */ jsx(
|
|
3083
|
+
BoundCompactPlayerView,
|
|
3084
|
+
{
|
|
3085
|
+
appearance,
|
|
3086
|
+
...className === void 0 ? {} : { className },
|
|
3087
|
+
commands: bound.commands,
|
|
3088
|
+
contextId: context.id,
|
|
3089
|
+
contextMode: context.mode,
|
|
3090
|
+
options: {
|
|
3091
|
+
seekCommitMode: player.state.experienceConfig.seekCommitMode,
|
|
3092
|
+
waveformOpacity: player.state.experienceConfig.waveformOpacity,
|
|
3093
|
+
waveformPlayedStateEnabled: player.state.experienceConfig.waveformPlayedStateEnabled
|
|
3094
|
+
},
|
|
3095
|
+
state: bound.state
|
|
3096
|
+
}
|
|
3097
|
+
);
|
|
3098
|
+
}
|
|
2390
3099
|
|
|
2391
|
-
export { MiniPlayerHost, PlayerProvider, usePlayer };
|
|
3100
|
+
export { BoundCompactPlayer, MiniPlayerHost, PlayerProvider, deriveBoundPlayerViewState, useBoundPlayer, usePlayer };
|
|
2392
3101
|
//# sourceMappingURL=index.js.map
|
|
2393
3102
|
//# sourceMappingURL=index.js.map
|