aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+videos/video-list
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-06-23 14:49:20 +0200
committerChocobozzz <chocobozzz@cpy.re>2020-06-23 16:00:49 +0200
commit1942f11d5ee6926ad93dc1b79fae18325ba5de18 (patch)
tree3f2a3cd9466a56c419d197ac832a3e9cbc86bec4 /client/src/app/+videos/video-list
parent67ed6552b831df66713bac9e672738796128d33f (diff)
downloadPeerTube-1942f11d5ee6926ad93dc1b79fae18325ba5de18.tar.gz
PeerTube-1942f11d5ee6926ad93dc1b79fae18325ba5de18.tar.zst
PeerTube-1942f11d5ee6926ad93dc1b79fae18325ba5de18.zip
Lazy load all routes
Diffstat (limited to 'client/src/app/+videos/video-list')
-rw-r--r--client/src/app/+videos/video-list/index.ts5
-rw-r--r--client/src/app/+videos/video-list/overview/index.ts3
-rw-r--r--client/src/app/+videos/video-list/overview/overview.service.ts78
-rw-r--r--client/src/app/+videos/video-list/overview/video-overview.component.html52
-rw-r--r--client/src/app/+videos/video-list/overview/video-overview.component.scss16
-rw-r--r--client/src/app/+videos/video-list/overview/video-overview.component.ts94
-rw-r--r--client/src/app/+videos/video-list/overview/videos-overview.model.ts20
-rw-r--r--client/src/app/+videos/video-list/video-local.component.ts86
-rw-r--r--client/src/app/+videos/video-list/video-most-liked.component.ts70
-rw-r--r--client/src/app/+videos/video-list/video-recently-added.component.ts74
-rw-r--r--client/src/app/+videos/video-list/video-trending.component.ts87
-rw-r--r--client/src/app/+videos/video-list/video-user-subscriptions.component.ts75
12 files changed, 660 insertions, 0 deletions
diff --git a/client/src/app/+videos/video-list/index.ts b/client/src/app/+videos/video-list/index.ts
new file mode 100644
index 000000000..af1bd58b7
--- /dev/null
+++ b/client/src/app/+videos/video-list/index.ts
@@ -0,0 +1,5 @@
1export * from './overview'
2export * from './video-local.component'
3export * from './video-recently-added.component'
4export * from './video-trending.component'
5export * from './video-most-liked.component'
diff --git a/client/src/app/+videos/video-list/overview/index.ts b/client/src/app/+videos/video-list/overview/index.ts
new file mode 100644
index 000000000..e6cfa4802
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/index.ts
@@ -0,0 +1,3 @@
1export * from './overview.service'
2export * from './video-overview.component'
3export * from './videos-overview.model'
diff --git a/client/src/app/+videos/video-list/overview/overview.service.ts b/client/src/app/+videos/video-list/overview/overview.service.ts
new file mode 100644
index 000000000..4458454d5
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/overview.service.ts
@@ -0,0 +1,78 @@
1import { forkJoin, Observable, of } from 'rxjs'
2import { catchError, map, switchMap, tap } from 'rxjs/operators'
3import { HttpClient, HttpParams } from '@angular/common/http'
4import { Injectable } from '@angular/core'
5import { RestExtractor, ServerService } from '@app/core'
6import { immutableAssign } from '@app/helpers'
7import { VideoService } from '@app/shared/shared-main'
8import { peertubeTranslate, VideosOverview as VideosOverviewServer } from '@shared/models'
9import { environment } from '../../../../environments/environment'
10import { VideosOverview } from './videos-overview.model'
11
12@Injectable()
13export class OverviewService {
14 static BASE_OVERVIEW_URL = environment.apiUrl + '/api/v1/overviews/'
15
16 constructor (
17 private authHttp: HttpClient,
18 private restExtractor: RestExtractor,
19 private videosService: VideoService,
20 private serverService: ServerService
21 ) {}
22
23 getVideosOverview (page: number): Observable<VideosOverview> {
24 let params = new HttpParams()
25 params = params.append('page', page + '')
26
27 return this.authHttp
28 .get<VideosOverviewServer>(OverviewService.BASE_OVERVIEW_URL + 'videos', { params })
29 .pipe(
30 switchMap(serverVideosOverview => this.updateVideosOverview(serverVideosOverview)),
31 catchError(err => this.restExtractor.handleError(err))
32 )
33 }
34
35 private updateVideosOverview (serverVideosOverview: VideosOverviewServer): Observable<VideosOverview> {
36 const observables: Observable<any>[] = []
37 const videosOverviewResult: VideosOverview = {
38 tags: [],
39 categories: [],
40 channels: []
41 }
42
43 // Build videos objects
44 for (const key of Object.keys(serverVideosOverview)) {
45 for (const object of serverVideosOverview[ key ]) {
46 observables.push(
47 of(object.videos)
48 .pipe(
49 switchMap(videos => this.videosService.extractVideos({ total: 0, data: videos })),
50 map(result => result.data),
51 tap(videos => {
52 videosOverviewResult[key].push(immutableAssign(object, { videos }))
53 })
54 )
55 )
56 }
57 }
58
59 if (observables.length === 0) return of(videosOverviewResult)
60
61 return forkJoin(observables)
62 .pipe(
63 // Translate categories
64 switchMap(() => {
65 return this.serverService.getServerLocale()
66 .pipe(
67 tap(translations => {
68 for (const c of videosOverviewResult.categories) {
69 c.category.label = peertubeTranslate(c.category.label, translations)
70 }
71 })
72 )
73 }),
74 map(() => videosOverviewResult)
75 )
76 }
77
78}
diff --git a/client/src/app/+videos/video-list/overview/video-overview.component.html b/client/src/app/+videos/video-list/overview/video-overview.component.html
new file mode 100644
index 000000000..ca986c634
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/video-overview.component.html
@@ -0,0 +1,52 @@
1<h1 class="sr-only" i18n>Discover</h1>
2<div class="margin-content">
3
4 <div class="no-results" i18n *ngIf="notResults">No results.</div>
5
6 <div
7 myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()"
8 >
9 <ng-container *ngFor="let overview of overviews">
10
11 <div class="section videos" *ngFor="let object of overview.categories">
12 <h1 class="section-title">
13 <a routerLink="/search" [queryParams]="{ categoryOneOf: [ object.category.id ] }">{{ object.category.label }}</a>
14 </h1>
15
16 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)">
17 <my-video-miniature [video]="video" [fitWidth]="true" [user]="userMiniature" [displayVideoActions]="true">
18 </my-video-miniature>
19 </div>
20 </div>
21
22 <div class="section videos" *ngFor="let object of overview.tags">
23 <h2 class="section-title">
24 <a routerLink="/search" [queryParams]="{ tagsOneOf: [ object.tag ] }">#{{ object.tag }}</a>
25 </h2>
26
27 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)">
28 <my-video-miniature [video]="video" [fitWidth]="true" [user]="userMiniature" [displayVideoActions]="true">
29 </my-video-miniature>
30 </div>
31 </div>
32
33 <div class="section channel videos" *ngFor="let object of overview.channels">
34 <div class="section-title">
35 <a [routerLink]="[ '/video-channels', buildVideoChannelBy(object) ]">
36 <img [src]="buildVideoChannelAvatarUrl(object)" alt="Avatar" />
37
38 <h2 class="section-title">{{ object.channel.displayName }}</h2>
39 </a>
40 </div>
41
42 <div class="video-wrapper" *ngFor="let video of buildVideos(object.videos)">
43 <my-video-miniature [video]="video" [fitWidth]="true" [user]="userMiniature" [displayVideoActions]="true">
44 </my-video-miniature>
45 </div>
46 </div>
47
48 </ng-container>
49
50 </div>
51
52</div>
diff --git a/client/src/app/+videos/video-list/overview/video-overview.component.scss b/client/src/app/+videos/video-list/overview/video-overview.component.scss
new file mode 100644
index 000000000..c1d10188a
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/video-overview.component.scss
@@ -0,0 +1,16 @@
1@import '_variables';
2@import '_mixins';
3@import '_miniature';
4
5.section-title {
6 // make the element span a full grid row within .videos grid
7 grid-column: 1 / -1;
8}
9
10.margin-content {
11 @include fluid-videos-miniature-layout;
12}
13
14.section {
15 @include miniature-rows;
16}
diff --git a/client/src/app/+videos/video-list/overview/video-overview.component.ts b/client/src/app/+videos/video-list/overview/video-overview.component.ts
new file mode 100644
index 000000000..b3be1d7b5
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/video-overview.component.ts
@@ -0,0 +1,94 @@
1import { Subject } from 'rxjs'
2import { Component, OnInit } from '@angular/core'
3import { Notifier, ScreenService, User, UserService } from '@app/core'
4import { Video } from '@app/shared/shared-main'
5import { OverviewService } from './overview.service'
6import { VideosOverview } from './videos-overview.model'
7
8@Component({
9 selector: 'my-video-overview',
10 templateUrl: './video-overview.component.html',
11 styleUrls: [ './video-overview.component.scss' ]
12})
13export class VideoOverviewComponent implements OnInit {
14 onDataSubject = new Subject<any>()
15
16 overviews: VideosOverview[] = []
17 notResults = false
18
19 userMiniature: User
20
21 private loaded = false
22 private currentPage = 1
23 private maxPage = 20
24 private lastWasEmpty = false
25 private isLoading = false
26
27 constructor (
28 private notifier: Notifier,
29 private userService: UserService,
30 private overviewService: OverviewService,
31 private screenService: ScreenService
32 ) { }
33
34 ngOnInit () {
35 this.loadMoreResults()
36
37 this.userService.getAnonymousOrLoggedUser()
38 .subscribe(user => this.userMiniature = user)
39
40 this.userService.listenAnonymousUpdate()
41 .subscribe(user => this.userMiniature = user)
42 }
43
44 buildVideoChannelBy (object: { videos: Video[] }) {
45 return object.videos[0].byVideoChannel
46 }
47
48 buildVideoChannelAvatarUrl (object: { videos: Video[] }) {
49 return object.videos[0].videoChannelAvatarUrl
50 }
51
52 buildVideos (videos: Video[]) {
53 const numberOfVideos = this.screenService.getNumberOfAvailableMiniatures()
54
55 return videos.slice(0, numberOfVideos * 2)
56 }
57
58 onNearOfBottom () {
59 if (this.currentPage >= this.maxPage) return
60 if (this.lastWasEmpty) return
61 if (this.isLoading) return
62
63 this.currentPage++
64 this.loadMoreResults()
65 }
66
67 private loadMoreResults () {
68 this.isLoading = true
69
70 this.overviewService.getVideosOverview(this.currentPage)
71 .subscribe(
72 overview => {
73 this.isLoading = false
74
75 if (overview.tags.length === 0 && overview.channels.length === 0 && overview.categories.length === 0) {
76 this.lastWasEmpty = true
77 if (this.loaded === false) this.notResults = true
78
79 return
80 }
81
82 this.loaded = true
83 this.onDataSubject.next(overview)
84
85 this.overviews.push(overview)
86 },
87
88 err => {
89 this.notifier.error(err.message)
90 this.isLoading = false
91 }
92 )
93 }
94}
diff --git a/client/src/app/+videos/video-list/overview/videos-overview.model.ts b/client/src/app/+videos/video-list/overview/videos-overview.model.ts
new file mode 100644
index 000000000..6765ad9b7
--- /dev/null
+++ b/client/src/app/+videos/video-list/overview/videos-overview.model.ts
@@ -0,0 +1,20 @@
1import { Video } from '@app/shared/shared-main'
2import { VideoChannelSummary, VideoConstant, VideosOverview as VideosOverviewServer } from '@shared/models'
3
4export class VideosOverview implements VideosOverviewServer {
5 channels: {
6 channel: VideoChannelSummary
7 videos: Video[]
8 }[]
9
10 categories: {
11 category: VideoConstant<number>
12 videos: Video[]
13 }[]
14
15 tags: {
16 tag: string
17 videos: Video[]
18 }[]
19 [key: string]: any
20}
diff --git a/client/src/app/+videos/video-list/video-local.component.ts b/client/src/app/+videos/video-list/video-local.component.ts
new file mode 100644
index 000000000..b4c71ac49
--- /dev/null
+++ b/client/src/app/+videos/video-list/video-local.component.ts
@@ -0,0 +1,86 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
4import { HooksService } from '@app/core/plugins/hooks.service'
5import { immutableAssign } from '@app/helpers'
6import { VideoService } from '@app/shared/shared-main'
7import { AbstractVideoList } from '@app/shared/shared-video-miniature'
8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { UserRight, VideoFilter, VideoSortField } from '@shared/models'
10
11@Component({
12 selector: 'my-videos-local',
13 styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ],
14 templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html'
15})
16export class VideoLocalComponent extends AbstractVideoList implements OnInit, OnDestroy {
17 titlePage: string
18 sort = '-publishedAt' as VideoSortField
19 filter: VideoFilter = 'local'
20
21 useUserVideoPreferences = true
22
23 constructor (
24 protected i18n: I18n,
25 protected router: Router,
26 protected serverService: ServerService,
27 protected route: ActivatedRoute,
28 protected notifier: Notifier,
29 protected authService: AuthService,
30 protected userService: UserService,
31 protected screenService: ScreenService,
32 protected storageService: LocalStorageService,
33 private videoService: VideoService,
34 private hooks: HooksService
35 ) {
36 super()
37
38 this.titlePage = i18n('Local videos')
39 }
40
41 ngOnInit () {
42 super.ngOnInit()
43
44 if (this.authService.isLoggedIn()) {
45 const user = this.authService.getUser()
46 this.displayModerationBlock = user.hasRight(UserRight.SEE_ALL_VIDEOS)
47 }
48
49 this.generateSyndicationList()
50 }
51
52 ngOnDestroy () {
53 super.ngOnDestroy()
54 }
55
56 getVideosObservable (page: number) {
57 const newPagination = immutableAssign(this.pagination, { currentPage: page })
58 const params = {
59 videoPagination: newPagination,
60 sort: this.sort,
61 filter: this.filter,
62 categoryOneOf: this.categoryOneOf,
63 languageOneOf: this.languageOneOf,
64 nsfwPolicy: this.nsfwPolicy,
65 skipCount: true
66 }
67
68 return this.hooks.wrapObsFun(
69 this.videoService.getVideos.bind(this.videoService),
70 params,
71 'common',
72 'filter:api.local-videos.videos.list.params',
73 'filter:api.local-videos.videos.list.result'
74 )
75 }
76
77 generateSyndicationList () {
78 this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, this.filter, this.categoryOneOf)
79 }
80
81 toggleModerationDisplay () {
82 this.filter = this.filter === 'local' ? 'all-local' as 'all-local' : 'local' as 'local'
83
84 this.reloadVideos()
85 }
86}
diff --git a/client/src/app/+videos/video-list/video-most-liked.component.ts b/client/src/app/+videos/video-list/video-most-liked.component.ts
new file mode 100644
index 000000000..ca14851bb
--- /dev/null
+++ b/client/src/app/+videos/video-list/video-most-liked.component.ts
@@ -0,0 +1,70 @@
1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
4import { HooksService } from '@app/core/plugins/hooks.service'
5import { immutableAssign } from '@app/helpers'
6import { VideoService } from '@app/shared/shared-main'
7import { AbstractVideoList } from '@app/shared/shared-video-miniature'
8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { VideoSortField } from '@shared/models'
10
11@Component({
12 selector: 'my-videos-most-liked',
13 styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ],
14 templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html'
15})
16export class VideoMostLikedComponent extends AbstractVideoList implements OnInit {
17 titlePage: string
18 defaultSort: VideoSortField = '-likes'
19
20 useUserVideoPreferences = true
21
22 constructor (
23 protected i18n: I18n,
24 protected router: Router,
25 protected serverService: ServerService,
26 protected route: ActivatedRoute,
27 protected notifier: Notifier,
28 protected authService: AuthService,
29 protected userService: UserService,
30 protected screenService: ScreenService,
31 protected storageService: LocalStorageService,
32 private videoService: VideoService,
33 private hooks: HooksService
34 ) {
35 super()
36 }
37
38 ngOnInit () {
39 super.ngOnInit()
40
41 this.generateSyndicationList()
42
43 this.titlePage = this.i18n('Most liked videos')
44 this.titleTooltip = this.i18n('Videos that have the higher number of likes.')
45 }
46
47 getVideosObservable (page: number) {
48 const newPagination = immutableAssign(this.pagination, { currentPage: page })
49 const params = {
50 videoPagination: newPagination,
51 sort: this.sort,
52 categoryOneOf: this.categoryOneOf,
53 languageOneOf: this.languageOneOf,
54 nsfwPolicy: this.nsfwPolicy,
55 skipCount: true
56 }
57
58 return this.hooks.wrapObsFun(
59 this.videoService.getVideos.bind(this.videoService),
60 params,
61 'common',
62 'filter:api.most-liked-videos.videos.list.params',
63 'filter:api.most-liked-videos.videos.list.result'
64 )
65 }
66
67 generateSyndicationList () {
68 this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf)
69 }
70}
diff --git a/client/src/app/+videos/video-list/video-recently-added.component.ts b/client/src/app/+videos/video-list/video-recently-added.component.ts
new file mode 100644
index 000000000..c9395133f
--- /dev/null
+++ b/client/src/app/+videos/video-list/video-recently-added.component.ts
@@ -0,0 +1,74 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
4import { HooksService } from '@app/core/plugins/hooks.service'
5import { immutableAssign } from '@app/helpers'
6import { VideoService } from '@app/shared/shared-main'
7import { AbstractVideoList } from '@app/shared/shared-video-miniature'
8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { VideoSortField } from '@shared/models'
10
11@Component({
12 selector: 'my-videos-recently-added',
13 styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ],
14 templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html'
15})
16export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy {
17 titlePage: string
18 sort: VideoSortField = '-publishedAt'
19 groupByDate = true
20
21 useUserVideoPreferences = true
22
23 constructor (
24 protected i18n: I18n,
25 protected route: ActivatedRoute,
26 protected serverService: ServerService,
27 protected router: Router,
28 protected notifier: Notifier,
29 protected authService: AuthService,
30 protected userService: UserService,
31 protected screenService: ScreenService,
32 protected storageService: LocalStorageService,
33 private videoService: VideoService,
34 private hooks: HooksService
35 ) {
36 super()
37
38 this.titlePage = i18n('Recently added')
39 }
40
41 ngOnInit () {
42 super.ngOnInit()
43
44 this.generateSyndicationList()
45 }
46
47 ngOnDestroy () {
48 super.ngOnDestroy()
49 }
50
51 getVideosObservable (page: number) {
52 const newPagination = immutableAssign(this.pagination, { currentPage: page })
53 const params = {
54 videoPagination: newPagination,
55 sort: this.sort,
56 categoryOneOf: this.categoryOneOf,
57 languageOneOf: this.languageOneOf,
58 nsfwPolicy: this.nsfwPolicy,
59 skipCount: true
60 }
61
62 return this.hooks.wrapObsFun(
63 this.videoService.getVideos.bind(this.videoService),
64 params,
65 'common',
66 'filter:api.recently-added-videos.videos.list.params',
67 'filter:api.recently-added-videos.videos.list.result'
68 )
69 }
70
71 generateSyndicationList () {
72 this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf)
73 }
74}
diff --git a/client/src/app/+videos/video-list/video-trending.component.ts b/client/src/app/+videos/video-list/video-trending.component.ts
new file mode 100644
index 000000000..10eab18de
--- /dev/null
+++ b/client/src/app/+videos/video-list/video-trending.component.ts
@@ -0,0 +1,87 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
4import { HooksService } from '@app/core/plugins/hooks.service'
5import { immutableAssign } from '@app/helpers'
6import { VideoService } from '@app/shared/shared-main'
7import { AbstractVideoList } from '@app/shared/shared-video-miniature'
8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { VideoSortField } from '@shared/models'
10
11@Component({
12 selector: 'my-videos-trending',
13 styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ],
14 templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html'
15})
16export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy {
17 titlePage: string
18 defaultSort: VideoSortField = '-trending'
19
20 useUserVideoPreferences = true
21
22 constructor (
23 protected i18n: I18n,
24 protected router: Router,
25 protected serverService: ServerService,
26 protected route: ActivatedRoute,
27 protected notifier: Notifier,
28 protected authService: AuthService,
29 protected userService: UserService,
30 protected screenService: ScreenService,
31 protected storageService: LocalStorageService,
32 private videoService: VideoService,
33 private hooks: HooksService
34 ) {
35 super()
36 }
37
38 ngOnInit () {
39 super.ngOnInit()
40
41 this.generateSyndicationList()
42
43 this.serverService.getConfig().subscribe(
44 config => {
45 const trendingDays = config.trending.videos.intervalDays
46
47 if (trendingDays === 1) {
48 this.titlePage = this.i18n('Trending for the last 24 hours')
49 this.titleTooltip = this.i18n('Trending videos are those totalizing the greatest number of views during the last 24 hours')
50 } else {
51 this.titlePage = this.i18n('Trending for the last {{days}} days', { days: trendingDays })
52 this.titleTooltip = this.i18n(
53 'Trending videos are those totalizing the greatest number of views during the last {{days}} days',
54 { days: trendingDays }
55 )
56 }
57 })
58 }
59
60 ngOnDestroy () {
61 super.ngOnDestroy()
62 }
63
64 getVideosObservable (page: number) {
65 const newPagination = immutableAssign(this.pagination, { currentPage: page })
66 const params = {
67 videoPagination: newPagination,
68 sort: this.sort,
69 categoryOneOf: this.categoryOneOf,
70 languageOneOf: this.languageOneOf,
71 nsfwPolicy: this.nsfwPolicy,
72 skipCount: true
73 }
74
75 return this.hooks.wrapObsFun(
76 this.videoService.getVideos.bind(this.videoService),
77 params,
78 'common',
79 'filter:api.trending-videos.videos.list.params',
80 'filter:api.trending-videos.videos.list.result'
81 )
82 }
83
84 generateSyndicationList () {
85 this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf)
86 }
87}
diff --git a/client/src/app/+videos/video-list/video-user-subscriptions.component.ts b/client/src/app/+videos/video-list/video-user-subscriptions.component.ts
new file mode 100644
index 000000000..41ad9b277
--- /dev/null
+++ b/client/src/app/+videos/video-list/video-user-subscriptions.component.ts
@@ -0,0 +1,75 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
4import { HooksService } from '@app/core/plugins/hooks.service'
5import { immutableAssign } from '@app/helpers'
6import { VideoService } from '@app/shared/shared-main'
7import { UserSubscriptionService } from '@app/shared/shared-user-subscription'
8import { AbstractVideoList, OwnerDisplayType } from '@app/shared/shared-video-miniature'
9import { I18n } from '@ngx-translate/i18n-polyfill'
10import { VideoSortField } from '@shared/models'
11
12@Component({
13 selector: 'my-videos-user-subscriptions',
14 styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ],
15 templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html'
16})
17export class VideoUserSubscriptionsComponent extends AbstractVideoList implements OnInit, OnDestroy {
18 titlePage: string
19 sort = '-publishedAt' as VideoSortField
20 ownerDisplayType: OwnerDisplayType = 'auto'
21 groupByDate = true
22
23 constructor (
24 protected i18n: I18n,
25 protected router: Router,
26 protected serverService: ServerService,
27 protected route: ActivatedRoute,
28 protected notifier: Notifier,
29 protected authService: AuthService,
30 protected userService: UserService,
31 protected screenService: ScreenService,
32 protected storageService: LocalStorageService,
33 private userSubscription: UserSubscriptionService,
34 private videoService: VideoService,
35 private hooks: HooksService
36 ) {
37 super()
38
39 this.titlePage = i18n('Videos from your subscriptions')
40 this.actions.push({
41 routerLink: '/my-account/subscriptions',
42 label: i18n('Subscriptions'),
43 iconName: 'cog'
44 })
45 }
46
47 ngOnInit () {
48 super.ngOnInit()
49 }
50
51 ngOnDestroy () {
52 super.ngOnDestroy()
53 }
54
55 getVideosObservable (page: number) {
56 const newPagination = immutableAssign(this.pagination, { currentPage: page })
57 const params = {
58 videoPagination: newPagination,
59 sort: this.sort,
60 skipCount: true
61 }
62
63 return this.hooks.wrapObsFun(
64 this.userSubscription.getUserSubscriptionVideos.bind(this.userSubscription),
65 params,
66 'common',
67 'filter:api.user-subscriptions-videos.videos.list.params',
68 'filter:api.user-subscriptions-videos.videos.list.result'
69 )
70 }
71
72 generateSyndicationList () {
73 // not implemented yet
74 }
75}