aboutsummaryrefslogtreecommitdiff
path: root/src/services/queue.ts
blob: 5db3b74933677eb841630cadf1dfded2ee0eda96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import shuffle from 'array-shuffle';

export interface QueuedPlaylist {
  title: string;
  source: string;
}

export interface QueuedSong {
  title: string;
  artist: string;
  url: string;
  length: number;
  playlist: QueuedPlaylist | null;
  isLive: boolean;
}

export default class {
  private queue: QueuedSong[] = [];
  private position = 0;

  forward(): void {
    if (this.position <= this.size() + 1) {
      this.position++;
    } else {
      throw new Error('No songs in queue to forward to.');
    }
  }

  back(): void {
    if (this.position - 1 >= 0) {
      this.position--;
    } else {
      throw new Error('No songs in queue to go back to.');
    }
  }

  getCurrent(): QueuedSong | null {
    if (this.queue[this.position]) {
      return this.queue[this.position];
    }

    return null;
  }

  get(): QueuedSong[] {
    return this.queue.slice(this.position + 1);
  }

  add(song: QueuedSong): void {
    if (song.playlist) {
      // Add to end of queue
      this.queue.push(song);
    } else {
      // Not from playlist, add immediately
      let insertAt = 0;

      // Loop until playlist song
      this.queue.some(song => {
        if (song.playlist) {
          return true;
        }

        insertAt++;
        return false;
      });

      this.queue = [...this.queue.slice(0, insertAt), song, ...this.queue.slice(insertAt)];
    }
  }

  shuffle(): void {
    this.queue = [...this.queue.slice(0, this.position), this.queue[this.position], this.queue[0], ...shuffle(this.queue.slice(this.position + 1))];
  }

  clear(): void {
    const newQueue = [];

    // Don't clear curently playing song
    if (this.queue.length > 0) {
      newQueue.push(this.queue[this.position]);
    }

    this.queue = newQueue;
  }

  size(): number {
    return this.get().length;
  }

  isEmpty(): boolean {
    return this.get().length === 0;
  }
}