]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/shared/shared-video-miniature/videos-list.component.ts
Merge branch 'release/5.0.0' into develop
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-video-miniature / videos-list.component.ts
index 9a7ec7efa2a4ed01388ba6f65d8b3761f5cb1dbb..7b832263e5bc0bdc974a7a4e9198fe8129c30429 100644 (file)
@@ -1,17 +1,27 @@
 import * as debug from 'debug'
 import { fromEvent, Observable, Subject, Subscription } from 'rxjs'
-import { debounceTime, switchMap } from 'rxjs/operators'
+import { concatMap, debounceTime, map, switchMap } from 'rxjs/operators'
 import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'
 import { ActivatedRoute } from '@angular/router'
-import { AuthService, ComponentPaginationLight, Notifier, PeerTubeRouterService, ScreenService, User, UserService } from '@app/core'
+import {
+  AuthService,
+  ComponentPaginationLight,
+  Notifier,
+  PeerTubeRouterService,
+  ScreenService,
+  ServerService,
+  User,
+  UserService
+} from '@app/core'
 import { GlobalIconName } from '@app/shared/shared-icons'
+import { logger } from '@root-helpers/logger'
 import { isLastMonth, isLastWeek, isThisMonth, isToday, isYesterday } from '@shared/core-utils'
 import { ResultList, UserRight, VideoSortField } from '@shared/models'
 import { Syndication, Video } from '../shared-main'
 import { VideoFilters, VideoFilterScope } from './video-filters.model'
 import { MiniatureDisplayOptions } from './video-miniature.component'
 
-const logger = debug('peertube:videos:VideosListComponent')
+const debugLogger = debug('peertube:videos:VideosListComponent')
 
 export type HeaderAction = {
   iconName: GlobalIconName
@@ -61,20 +71,12 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
 
   @Input() hideScopeFilter = false
 
-  @Input() displayOptions: MiniatureDisplayOptions = {
-    date: true,
-    views: true,
-    by: true,
-    avatar: false,
-    privacyLabel: true,
-    privacyText: false,
-    state: false,
-    blacklistInfo: false
-  }
+  @Input() displayOptions: MiniatureDisplayOptions
 
   @Input() disabled = false
 
   @Output() filtersChanged = new EventEmitter<VideoFilters>()
+  @Output() videosLoaded = new EventEmitter<Video[]>()
 
   videos: Video[] = []
   filters: VideoFilters
@@ -85,6 +87,16 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
 
   userMiniature: User
 
+  private defaultDisplayOptions: MiniatureDisplayOptions = {
+    date: true,
+    views: true,
+    by: true,
+    avatar: false,
+    privacyLabel: true,
+    privacyText: false,
+    state: false,
+    blacklistInfo: false
+  }
   private routeSub: Subscription
   private userSub: Subscription
   private resizeSub: Subscription
@@ -99,18 +111,23 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
 
   private lastQueryLength: number
 
+  private videoRequests = new Subject<{ reset: boolean, obs: Observable<ResultList<Video>> }>()
+
   constructor (
     private notifier: Notifier,
     private authService: AuthService,
     private userService: UserService,
     private route: ActivatedRoute,
     private screenService: ScreenService,
-    private peertubeRouter: PeerTubeRouterService
+    private peertubeRouter: PeerTubeRouterService,
+    private serverService: ServerService
   ) {
 
   }
 
   ngOnInit () {
+    this.subscribeToVideoRequests()
+
     const hiddenFilters = this.hideScopeFilter
       ? [ 'scope' ]
       : []
@@ -161,6 +178,14 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
   }
 
   ngOnChanges (changes: SimpleChanges) {
+    if (changes['displayOptions'] || !this.displayOptions) {
+      this.displayOptions = {
+        ...this.defaultDisplayOptions,
+        avatar: this.serverService.getHTMLConfig().client.videos.miniature.displayAuthorAvatar,
+        ...changes['displayOptions']
+      }
+    }
+
     if (!this.filters) return
 
     let updated = false
@@ -207,29 +232,12 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
   }
 
   loadMoreVideos (reset = false) {
-    if (reset) this.hasDoneFirstQuery = false
-
-    this.getVideosObservableFunction(this.pagination, this.filters)
-      .subscribe({
-        next: ({ data }) => {
-          this.hasDoneFirstQuery = true
-          this.lastQueryLength = data.length
-
-          if (reset) this.videos = []
-          this.videos = this.videos.concat(data)
-
-          if (this.groupByDate) this.buildGroupedDateLabels()
-
-          this.onDataSubject.next(data)
-        },
-
-        error: err => {
-          const message = $localize`Cannot load more videos. Try again later.`
+    if (reset) {
+      this.hasDoneFirstQuery = false
+      this.videos = []
+    }
 
-          console.error(message, { err })
-          this.notifier.error(message)
-        }
-      })
+    this.videoRequests.next({ reset, obs: this.getVideosObservableFunction(this.pagination, this.filters) })
   }
 
   reloadVideos () {
@@ -304,7 +312,7 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
   }
 
   onFiltersChanged (customizedByUser: boolean) {
-    logger('Running on filters changed')
+    debugLogger('Running on filters changed')
 
     this.updateUrl(customizedByUser)
 
@@ -345,7 +353,7 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
         if (!items || items.length === 0) this.syndicationItems = undefined
         else this.syndicationItems = items
       })
-      .catch(err => console.error('Cannot get syndication items.', err))
+      .catch(err => logger.error('Cannot get syndication items.', err))
   }
 
   private updateUrl (customizedByUser: boolean) {
@@ -356,7 +364,7 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
       ? { ...baseQuery, c: customizedByUser }
       : baseQuery
 
-    logger('Will inject %O in URL query', queryParams)
+    debugLogger('Will inject %O in URL query', queryParams)
 
     const baseRoute = this.baseRouteBuilderFunction
       ? this.baseRouteBuilderFunction(this.filters)
@@ -401,4 +409,30 @@ export class VideosListComponent implements OnInit, OnChanges, OnDestroy {
       this.onFiltersChanged(true)
     })
   }
+
+  private subscribeToVideoRequests () {
+    this.videoRequests
+      .pipe(concatMap(({ reset, obs }) => obs.pipe(map(({ data }) => ({ data, reset })))))
+      .subscribe({
+        next: ({ data, reset }) => {
+          this.hasDoneFirstQuery = true
+          this.lastQueryLength = data.length
+
+          if (reset) this.videos = []
+          this.videos = this.videos.concat(data)
+
+          if (this.groupByDate) this.buildGroupedDateLabels()
+
+          this.onDataSubject.next(data)
+          this.videosLoaded.emit(this.videos)
+        },
+
+        error: err => {
+          const message = $localize`Cannot load more videos. Try again later.`
+
+          logger.error(message, err)
+          this.notifier.error(message)
+        }
+      })
+  }
 }