webamp 0.0.0-next-a180155 → 0.0.0-next-c1d68b5

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.
@@ -0,0 +1,2 @@
1
+ import type WebampLazy from "./webampLazy";
2
+ export default function enableMediaSession(webamp: WebampLazy): void;
@@ -0,0 +1 @@
1
+ export declare function setImmediate(callback: Function): number;
@@ -584,6 +584,15 @@ export interface Options {
584
584
  handleAddUrlEvent?: () => Track[] | null | Promise<Track[] | null>;
585
585
  handleLoadListEvent?: () => Track[] | null | Promise<Track[] | null>;
586
586
  handleSaveListEvent?: (tracks: Track[]) => null | Promise<null>;
587
+ /**
588
+ * Have Webamp attempt to connect to the browser's media session API.
589
+ *
590
+ * This allows OS/hardware level media controls like play/pause/next/previous
591
+ * and lock screen "current track" information to work with Webamp.
592
+ *
593
+ * https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API
594
+ */
595
+ enableMediaSession?: boolean;
587
596
  }
588
597
  /**
589
598
  * Specifies the initial position and size of a the Winamp windows.
@@ -61,10 +61,18 @@ declare class Webamp {
61
61
  * Check if shuffle is enabled
62
62
  */
63
63
  isShuffleEnabled(): boolean;
64
+ /**
65
+ * Toggle shuffle mode between enabled and disabled.
66
+ */
67
+ toggleShuffle(): void;
64
68
  /**
65
69
  * Check if repeat is enabled
66
70
  */
67
71
  isRepeatEnabled(): boolean;
72
+ /**
73
+ * Toggle repeat mode between enabled and disabled.
74
+ */
75
+ toggleRepeat(): void;
68
76
  /**
69
77
  * Play the next track
70
78
  */
@@ -43991,6 +43991,57 @@
43991
43991
  }
43992
43992
  }
43993
43993
 
43994
+ function enableMediaSession(webamp) {
43995
+ if ("mediaSession" in navigator) {
43996
+ /* global MediaMetadata */
43997
+ webamp.onTrackDidChange((track) => {
43998
+ if (track == null) {
43999
+ return;
44000
+ }
44001
+ const { metaData: { title, artist, album, albumArtUrl }, } = track;
44002
+ navigator.mediaSession.metadata = new MediaMetadata({
44003
+ title: title ?? undefined,
44004
+ artist: artist ?? undefined,
44005
+ album: album ?? undefined,
44006
+ artwork: albumArtUrl
44007
+ ? [
44008
+ {
44009
+ src: albumArtUrl,
44010
+ // We don't currently know these.
44011
+ // sizes: "96x96",
44012
+ // type: "image/png"
44013
+ },
44014
+ ]
44015
+ : [],
44016
+ });
44017
+ });
44018
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44019
+ navigator.mediaSession.setActionHandler("play", () => {
44020
+ webamp.play();
44021
+ });
44022
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44023
+ navigator.mediaSession.setActionHandler("pause", () => {
44024
+ webamp.pause();
44025
+ });
44026
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44027
+ navigator.mediaSession.setActionHandler("seekbackward", () => {
44028
+ webamp.seekBackward(10);
44029
+ });
44030
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44031
+ navigator.mediaSession.setActionHandler("seekforward", () => {
44032
+ webamp.seekForward(10);
44033
+ });
44034
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44035
+ navigator.mediaSession.setActionHandler("previoustrack", () => {
44036
+ webamp.previousTrack();
44037
+ });
44038
+ // @ts-ignore TypeScript does not know about the Media Session API: https://github.com/Microsoft/TypeScript/issues/19473
44039
+ navigator.mediaSession.setActionHandler("nexttrack", () => {
44040
+ webamp.nextTrack();
44041
+ });
44042
+ }
44043
+ }
44044
+
43994
44045
  let Webamp$1 = class Webamp {
43995
44046
  static VERSION = "1.5.0";
43996
44047
  _actionEmitter;
@@ -44018,6 +44069,9 @@
44018
44069
  this._actionEmitter = new Emitter();
44019
44070
  this.options = options;
44020
44071
  const { initialTracks, initialSkin, availableSkins, enableHotkeys = false, zIndex, requireJSZip, requireMusicMetadata, handleTrackDropEvent, handleAddUrlEvent, handleLoadListEvent, handleSaveListEvent, enableDoubleSizeMode, __butterchurnOptions, __customMediaClass, } = this.options;
44072
+ if (options.enableMediaSession) {
44073
+ enableMediaSession(this);
44074
+ }
44021
44075
  // TODO: Make this much cleaner
44022
44076
  let convertPreset = null;
44023
44077
  if (__butterchurnOptions != null) {
@@ -44140,12 +44194,24 @@
44140
44194
  isShuffleEnabled() {
44141
44195
  return getShuffle(this.store.getState());
44142
44196
  }
44197
+ /**
44198
+ * Toggle shuffle mode between enabled and disabled.
44199
+ */
44200
+ toggleShuffle() {
44201
+ this.store.dispatch(toggleShuffle());
44202
+ }
44143
44203
  /**
44144
44204
  * Check if repeat is enabled
44145
44205
  */
44146
44206
  isRepeatEnabled() {
44147
44207
  return getRepeat(this.store.getState());
44148
44208
  }
44209
+ /**
44210
+ * Toggle repeat mode between enabled and disabled.
44211
+ */
44212
+ toggleRepeat() {
44213
+ this.store.dispatch(toggleRepeat());
44214
+ }
44149
44215
  /**
44150
44216
  * Play the next track
44151
44217
  */
@@ -44367,6 +44433,125 @@
44367
44433
  // @ts-ignore
44368
44434
  window.Webamp = Webamp$1;
44369
44435
 
44436
+ // A Fork of the NPM module `setimmediate`
44437
+ // I've adapted this to only include the browser implementation and to not
44438
+ // mutate the global object and instead export the `setImmediate` function.
44439
+ let nextHandle = 1; // Spec says greater than zero
44440
+ const tasksByHandle = {};
44441
+ let currentlyRunningATask = false;
44442
+ let registerImmediate;
44443
+ function setImmediate$1(callback) {
44444
+ // Copy function arguments
44445
+ const args = new Array(arguments.length - 1);
44446
+ for (let i = 0; i < args.length; i++) {
44447
+ args[i] = arguments[i + 1];
44448
+ }
44449
+ // Store and register the task
44450
+ const task = { callback: callback, args: args };
44451
+ tasksByHandle[nextHandle] = task;
44452
+ registerImmediate(nextHandle);
44453
+ return nextHandle++;
44454
+ }
44455
+ function clearImmediate(handle) {
44456
+ delete tasksByHandle[handle];
44457
+ }
44458
+ function run(task) {
44459
+ const callback = task.callback;
44460
+ const args = task.args;
44461
+ switch (args.length) {
44462
+ case 0:
44463
+ callback();
44464
+ break;
44465
+ case 1:
44466
+ callback(args[0]);
44467
+ break;
44468
+ case 2:
44469
+ callback(args[0], args[1]);
44470
+ break;
44471
+ case 3:
44472
+ callback(args[0], args[1], args[2]);
44473
+ break;
44474
+ default:
44475
+ // eslint-disable-next-line prefer-spread
44476
+ callback.apply(undefined, args);
44477
+ break;
44478
+ }
44479
+ }
44480
+ function runIfPresent(handle) {
44481
+ // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
44482
+ // So if we're currently running a task, we'll need to delay this invocation.
44483
+ if (currentlyRunningATask) {
44484
+ // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
44485
+ // "too much recursion" error.
44486
+ setTimeout(runIfPresent, 0, handle);
44487
+ }
44488
+ else {
44489
+ const task = tasksByHandle[handle];
44490
+ if (task) {
44491
+ currentlyRunningATask = true;
44492
+ try {
44493
+ run(task);
44494
+ }
44495
+ finally {
44496
+ clearImmediate(handle);
44497
+ currentlyRunningATask = false;
44498
+ }
44499
+ }
44500
+ }
44501
+ }
44502
+ function canUsePostMessage() {
44503
+ // The test against `importScripts` prevents this implementation from being installed inside a web worker,
44504
+ // where `global.postMessage` means something completely different and can't be used for this purpose.
44505
+ if (!window.importScripts) {
44506
+ let postMessageIsAsynchronous = true;
44507
+ const oldOnMessage = window.onmessage;
44508
+ window.onmessage = function () {
44509
+ postMessageIsAsynchronous = false;
44510
+ };
44511
+ window.postMessage("", "*");
44512
+ window.onmessage = oldOnMessage;
44513
+ return postMessageIsAsynchronous;
44514
+ }
44515
+ }
44516
+ function installPostMessageImplementation() {
44517
+ // Installs an event handler on `global` for the `message` event: see
44518
+ // * https://developer.mozilla.org/en/DOM/window.postMessage
44519
+ // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
44520
+ const messagePrefix = `setImmediate$${Math.random()}$`;
44521
+ window.addEventListener("message", (event) => {
44522
+ if (event.source === window &&
44523
+ typeof event.data === "string" &&
44524
+ event.data.indexOf(messagePrefix) === 0) {
44525
+ runIfPresent(+event.data.slice(messagePrefix.length));
44526
+ }
44527
+ }, false);
44528
+ registerImmediate = function (handle) {
44529
+ window.postMessage(messagePrefix + handle, "*");
44530
+ };
44531
+ }
44532
+ function installSetTimeoutImplementation() {
44533
+ registerImmediate = function (handle) {
44534
+ setTimeout(runIfPresent, 0, handle);
44535
+ };
44536
+ }
44537
+ if (canUsePostMessage()) {
44538
+ // For non-IE10 modern browsers
44539
+ installPostMessageImplementation();
44540
+ }
44541
+ else {
44542
+ // For older browsers
44543
+ installSetTimeoutImplementation();
44544
+ }
44545
+
44546
+ var utilsExports = requireUtils();
44547
+ var Utils = /*@__PURE__*/getDefaultExportFromCjs(utilsExports);
44548
+
44549
+ // @ts-ignore
44550
+ Utils.delay = function (callback, args, self) {
44551
+ setImmediate$1(() => {
44552
+ callback.apply(self || null, args || []);
44553
+ });
44554
+ };
44370
44555
  class Webamp extends Webamp$1 {
44371
44556
  constructor(options) {
44372
44557
  super({