magmastream 2.9.0-dev.22 → 2.9.0-dev.24

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.d.ts CHANGED
@@ -1528,6 +1528,7 @@ declare class Player {
1528
1528
  autoplayTries: number;
1529
1529
  private static _manager;
1530
1530
  private readonly data;
1531
+ private volumeFadeInProgress;
1531
1532
  private dynamicLoopInterval;
1532
1533
  dynamicRepeatIntervalMs: number | null;
1533
1534
  /**
@@ -1643,14 +1644,16 @@ declare class Player {
1643
1644
  /**
1644
1645
  * Sets the volume of the player.
1645
1646
  * @param {number} volume - The new volume. Must be between 0 and 1000.
1647
+ * @param {GradualOptions} options - The options to use for the gradual change.
1646
1648
  * @returns {Promise<Player>} - The updated player.
1647
1649
  * @throws {TypeError} If the volume is not a number.
1648
1650
  * @throws {RangeError} If the volume is not between 0 and 1000.
1649
1651
  * @emits {PlayerStateUpdate} - Emitted when the volume is changed.
1650
1652
  * @example
1651
1653
  * player.setVolume(50);
1654
+ * player.setVolume(50, { gradual: true, interval: 50, step: 5 });
1652
1655
  */
1653
- setVolume(volume: number): Promise<this>;
1656
+ setVolume(volume: number, options?: GradualOptions): Promise<this>;
1654
1657
  /**
1655
1658
  * Sets the sponsorblock for the player. This will set the sponsorblock segments for the player to the given segments.
1656
1659
  * @param {SponsorBlockSegment[]} segments - The sponsorblock segments to set. Defaults to `[SponsorBlockSegment.Sponsor, SponsorBlockSegment.SelfPromo]` if not provided.
@@ -1761,6 +1764,12 @@ declare class Player {
1761
1764
  * @throws {RangeError} - If the 'lavalyrics-plugin' is not available on the Lavalink node.
1762
1765
  */
1763
1766
  getCurrentLyrics(skipTrackSource?: boolean): Promise<Lyrics>;
1767
+ /**
1768
+ * Sleeps for a specified amount of time.
1769
+ * @param ms The amount of time to sleep in milliseconds.
1770
+ * @returns A promise that resolves after the specified amount of time.
1771
+ */
1772
+ private sleep;
1764
1773
  }
1765
1774
  interface PlayerOptions {
1766
1775
  /** The guild ID the Player belongs to. */
@@ -1778,6 +1787,14 @@ interface PlayerOptions {
1778
1787
  /** If the player should deaf itself. */
1779
1788
  selfDeafen?: boolean;
1780
1789
  }
1790
+ interface GradualOptions {
1791
+ /** If the change should be gradual. */
1792
+ gradual?: boolean;
1793
+ /** The duration of the gradual change. */
1794
+ interval?: number;
1795
+ /** The step of the gradual change. */
1796
+ step?: number;
1797
+ }
1781
1798
  /** If track partials are set some of these will be `undefined` as they were removed. */
1782
1799
  interface Track {
1783
1800
  /** The base64 encoded track. */
@@ -2260,4 +2277,4 @@ declare class Plugin {
2260
2277
  }
2261
2278
 
2262
2279
  export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, Filters, LoadTypes, Manager, ManagerEventTypes, Node, Player, PlayerStateEventTypes, Plugin, Queue, Rest, SearchPlatform, SeverityTypes, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
2263
- export type { CPUStats, EqualizerBand, Exception, Extendable, FrameStats, IQueue, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsLine, ManagerEvents, ManagerOptions, MemoryStats, NodeMessage, NodeOptions, NodeStats, Payload, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStore, PlayerUpdate, PlaylistData, PlaylistInfoData, PlaylistRawData, RedisConfig, SearchQuery, SearchResult, Severity, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, State, StateStorageOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent };
2280
+ export type { CPUStats, EqualizerBand, Exception, Extendable, FrameStats, GradualOptions, IQueue, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsLine, ManagerEvents, ManagerOptions, MemoryStats, NodeMessage, NodeOptions, NodeStats, Payload, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStore, PlayerUpdate, PlaylistData, PlaylistInfoData, PlaylistRawData, RedisConfig, SearchQuery, SearchResult, Severity, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, State, StateStorageOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent };
@@ -54,6 +54,7 @@ class Player {
54
54
  autoplayTries = 3;
55
55
  static _manager;
56
56
  data = {};
57
+ volumeFadeInProgress = false;
57
58
  dynamicLoopInterval = null;
58
59
  dynamicRepeatIntervalMs = null;
59
60
  /**
@@ -392,30 +393,66 @@ class Player {
392
393
  /**
393
394
  * Sets the volume of the player.
394
395
  * @param {number} volume - The new volume. Must be between 0 and 1000.
396
+ * @param {GradualOptions} options - The options to use for the gradual change.
395
397
  * @returns {Promise<Player>} - The updated player.
396
398
  * @throws {TypeError} If the volume is not a number.
397
399
  * @throws {RangeError} If the volume is not between 0 and 1000.
398
400
  * @emits {PlayerStateUpdate} - Emitted when the volume is changed.
399
401
  * @example
400
402
  * player.setVolume(50);
403
+ * player.setVolume(50, { gradual: true, interval: 50, step: 5 });
401
404
  */
402
- async setVolume(volume) {
405
+ async setVolume(volume, options) {
403
406
  if (isNaN(volume))
404
407
  throw new TypeError("Volume must be a number.");
405
408
  if (volume < 0 || volume > 1000)
406
409
  throw new RangeError("Volume must be between 0 and 1000.");
407
- const oldPlayer = this ? { ...this } : null;
408
- await this.node.rest.updatePlayer({
409
- guildId: this.options.guildId,
410
- data: {
411
- volume,
412
- },
413
- });
414
- this.volume = volume;
415
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
416
- changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
417
- details: { previousVolume: oldPlayer.volume || null, currentVolume: this.volume },
418
- });
410
+ const oldVolume = this.volume;
411
+ if (options?.gradual) {
412
+ if (this.volumeFadeInProgress) {
413
+ throw new Error("A volume fade is already in progress.");
414
+ }
415
+ this.volumeFadeInProgress = true;
416
+ const interval = options.interval ?? 100;
417
+ const step = options.step ?? 5;
418
+ const direction = volume > this.volume ? 1 : -1;
419
+ let currentVolume = this.volume;
420
+ while (currentVolume !== volume) {
421
+ currentVolume = direction > 0 ? Math.min(currentVolume + step, volume) : Math.max(currentVolume - step, volume);
422
+ await this.node.rest.updatePlayer({
423
+ guildId: this.options.guildId,
424
+ data: { volume: currentVolume },
425
+ });
426
+ this.volume = currentVolume;
427
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, {
428
+ changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
429
+ details: {
430
+ previousVolume: oldVolume,
431
+ currentVolume: this.volume,
432
+ isGradual: true,
433
+ },
434
+ });
435
+ if (currentVolume !== volume) {
436
+ await this.sleep(interval);
437
+ }
438
+ }
439
+ this.volumeFadeInProgress = false;
440
+ }
441
+ else {
442
+ await this.node.rest.updatePlayer({
443
+ guildId: this.options.guildId,
444
+ data: { volume },
445
+ });
446
+ this.volume = volume;
447
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, {
448
+ changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
449
+ details: {
450
+ previousVolume: oldVolume,
451
+ currentVolume: this.volume,
452
+ isGradual: false,
453
+ },
454
+ });
455
+ }
419
456
  return this;
420
457
  }
421
458
  /**
@@ -901,5 +938,13 @@ class Player {
901
938
  }
902
939
  return result;
903
940
  }
941
+ /**
942
+ * Sleeps for a specified amount of time.
943
+ * @param ms The amount of time to sleep in milliseconds.
944
+ * @returns A promise that resolves after the specified amount of time.
945
+ */
946
+ sleep(ms) {
947
+ return new Promise((resolve) => setTimeout(resolve, ms));
948
+ }
904
949
  }
905
950
  exports.Player = Player;
@@ -37,10 +37,14 @@ class Queue extends Array {
37
37
  }
38
38
  async addPrevious(track) {
39
39
  if (Array.isArray(track)) {
40
- this.previous.unshift(...track);
40
+ const newTracks = track.filter((t) => !this.previous.some((p) => p.identifier === t.identifier));
41
+ this.previous.unshift(...newTracks);
41
42
  }
42
43
  else {
43
- this.previous.unshift(track);
44
+ const exists = this.previous.some((p) => p.identifier === track.identifier);
45
+ if (!exists) {
46
+ this.previous.unshift(track);
47
+ }
44
48
  }
45
49
  }
46
50
  async setPrevious(tracks) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.0-dev.22",
3
+ "version": "2.9.0-dev.24",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -90,4 +90,4 @@
90
90
  "homepage": "https://docs.magmastream.com",
91
91
  "author": "Abel Purnwasy",
92
92
  "license": "Apache-2.0"
93
- }
93
+ }