WIP plugins: update plugin
[oweals/peertube.git] / client / src / app / shared / overview / overview.service.ts
1 import { catchError, map, switchMap, tap } from 'rxjs/operators'
2 import { HttpClient } from '@angular/common/http'
3 import { Injectable } from '@angular/core'
4 import { forkJoin, Observable, of } from 'rxjs'
5 import { VideosOverview as VideosOverviewServer, peertubeTranslate } from '../../../../../shared/models'
6 import { environment } from '../../../environments/environment'
7 import { RestExtractor } from '../rest/rest-extractor.service'
8 import { VideosOverview } from '@app/shared/overview/videos-overview.model'
9 import { VideoService } from '@app/shared/video/video.service'
10 import { ServerService } from '@app/core'
11 import { immutableAssign } from '@app/shared/misc/utils'
12
13 @Injectable()
14 export class OverviewService {
15   static BASE_OVERVIEW_URL = environment.apiUrl + '/api/v1/overviews/'
16
17   constructor (
18     private authHttp: HttpClient,
19     private restExtractor: RestExtractor,
20     private videosService: VideoService,
21     private serverService: ServerService
22   ) {}
23
24   getVideosOverview (): Observable<VideosOverview> {
25     return this.authHttp
26                .get<VideosOverviewServer>(OverviewService.BASE_OVERVIEW_URL + 'videos')
27                .pipe(
28                  switchMap(serverVideosOverview => this.updateVideosOverview(serverVideosOverview)),
29                  catchError(err => this.restExtractor.handleError(err))
30                )
31   }
32
33   private updateVideosOverview (serverVideosOverview: VideosOverviewServer): Observable<VideosOverview> {
34     const observables: Observable<any>[] = []
35     const videosOverviewResult: VideosOverview = {
36       tags: [],
37       categories: [],
38       channels: []
39     }
40
41     // Build videos objects
42     for (const key of Object.keys(serverVideosOverview)) {
43       for (const object of serverVideosOverview[ key ]) {
44         observables.push(
45           of(object.videos)
46             .pipe(
47               switchMap(videos => this.videosService.extractVideos({ total: 0, data: videos })),
48               map(result => result.videos),
49               tap(videos => {
50                 videosOverviewResult[key].push(immutableAssign(object, { videos }))
51               })
52             )
53         )
54       }
55     }
56
57     if (observables.length === 0) return of(videosOverviewResult)
58
59     return forkJoin(observables)
60       .pipe(
61         // Translate categories
62         switchMap(() => {
63           return this.serverService.localeObservable
64               .pipe(
65                 tap(translations => {
66                   for (const c of videosOverviewResult.categories) {
67                     c.category.label = peertubeTranslate(c.category.label, translations)
68                   }
69                 })
70               )
71         }),
72         map(() => videosOverviewResult)
73       )
74   }
75
76 }