aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/standalone/videos/shared/playlist-fetcher.ts
blob: a7e72c177c901699fd744831e0cbf709af36b3e6 (plain) (blame)
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
import { HttpStatusCode, ResultList, VideoPlaylistElement } from '../../../../../shared/models'
import { AuthHTTP } from './auth-http'

export class PlaylistFetcher {

  constructor (private readonly http: AuthHTTP) {

  }

  async loadPlaylist (playlistId: string) {
    const playlistPromise = this.loadPlaylistInfo(playlistId)
    const playlistElementsPromise = this.loadPlaylistElements(playlistId)

    let playlistResponse: Response
    let isResponseOk: boolean

    try {
      playlistResponse = await playlistPromise
      isResponseOk = playlistResponse.status === HttpStatusCode.OK_200
    } catch (err) {
      console.error(err)
      isResponseOk = false
    }

    if (!isResponseOk) {
      if (playlistResponse?.status === HttpStatusCode.NOT_FOUND_404) {
        throw new Error('This playlist does not exist.')
      }

      throw new Error('We cannot fetch the playlist. Please try again later.')
    }

    return { playlistResponse, videosResponse: await playlistElementsPromise }
  }

  async loadAllPlaylistVideos (playlistId: string, baseResult: ResultList<VideoPlaylistElement>) {
    let elements = baseResult.data
    let total = baseResult.total
    let i = 0

    while (total > elements.length && i < 10) {
      const result = await this.loadPlaylistElements(playlistId, elements.length)

      const json = await result.json()
      total = json.total

      elements = elements.concat(json.data)
      i++
    }

    if (i === 10) {
      console.error('Cannot fetch all playlists elements, there are too many!')
    }

    return elements
  }

  private loadPlaylistInfo (playlistId: string): Promise<Response> {
    return this.http.fetch(this.getPlaylistUrl(playlistId), { optionalAuth: true })
  }

  private loadPlaylistElements (playlistId: string, start = 0): Promise<Response> {
    const url = new URL(this.getPlaylistUrl(playlistId) + '/videos')
    url.search = new URLSearchParams({ start: '' + start, count: '100' }).toString()

    return this.http.fetch(url.toString(), { optionalAuth: true })
  }

  private getPlaylistUrl (id: string) {
    return window.location.origin + '/api/v1/video-playlists/' + id
  }
}