From 67ed6552b831df66713bac9e672738796128d33f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Jun 2020 14:10:17 +0200 Subject: Reorganize client shared modules --- client/src/app/videos/video-list/index.ts | 1 + client/src/app/videos/video-list/overview/index.ts | 3 + .../videos/video-list/overview/overview.service.ts | 78 ++++++++++++++++++ .../overview/video-overview.component.html | 52 ++++++++++++ .../overview/video-overview.component.scss | 16 ++++ .../overview/video-overview.component.ts | 94 +++++++++++++++++++++ .../video-list/overview/videos-overview.model.ts | 20 +++++ .../app/videos/video-list/video-local.component.ts | 22 ++--- .../video-list/video-most-liked.component.ts | 20 ++--- .../video-list/video-overview.component.html | 52 ------------ .../video-list/video-overview.component.scss | 16 ---- .../videos/video-list/video-overview.component.ts | 96 ---------------------- .../video-list/video-recently-added.component.ts | 20 ++--- .../videos/video-list/video-trending.component.ts | 20 ++--- .../video-user-subscriptions.component.ts | 25 +++--- 15 files changed, 307 insertions(+), 228 deletions(-) create mode 100644 client/src/app/videos/video-list/overview/index.ts create mode 100644 client/src/app/videos/video-list/overview/overview.service.ts create mode 100644 client/src/app/videos/video-list/overview/video-overview.component.html create mode 100644 client/src/app/videos/video-list/overview/video-overview.component.scss create mode 100644 client/src/app/videos/video-list/overview/video-overview.component.ts create mode 100644 client/src/app/videos/video-list/overview/videos-overview.model.ts delete mode 100644 client/src/app/videos/video-list/video-overview.component.html delete mode 100644 client/src/app/videos/video-list/video-overview.component.scss delete mode 100644 client/src/app/videos/video-list/video-overview.component.ts (limited to 'client/src/app/videos/video-list') diff --git a/client/src/app/videos/video-list/index.ts b/client/src/app/videos/video-list/index.ts index b367110ae..af1bd58b7 100644 --- a/client/src/app/videos/video-list/index.ts +++ b/client/src/app/videos/video-list/index.ts @@ -1,3 +1,4 @@ +export * from './overview' export * from './video-local.component' export * from './video-recently-added.component' export * from './video-trending.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 @@ +export * from './overview.service' +export * from './video-overview.component' +export * 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 @@ +import { forkJoin, Observable, of } from 'rxjs' +import { catchError, map, switchMap, tap } from 'rxjs/operators' +import { HttpClient, HttpParams } from '@angular/common/http' +import { Injectable } from '@angular/core' +import { RestExtractor, ServerService } from '@app/core' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { peertubeTranslate, VideosOverview as VideosOverviewServer } from '@shared/models' +import { environment } from '../../../../environments/environment' +import { VideosOverview } from './videos-overview.model' + +@Injectable() +export class OverviewService { + static BASE_OVERVIEW_URL = environment.apiUrl + '/api/v1/overviews/' + + constructor ( + private authHttp: HttpClient, + private restExtractor: RestExtractor, + private videosService: VideoService, + private serverService: ServerService + ) {} + + getVideosOverview (page: number): Observable { + let params = new HttpParams() + params = params.append('page', page + '') + + return this.authHttp + .get(OverviewService.BASE_OVERVIEW_URL + 'videos', { params }) + .pipe( + switchMap(serverVideosOverview => this.updateVideosOverview(serverVideosOverview)), + catchError(err => this.restExtractor.handleError(err)) + ) + } + + private updateVideosOverview (serverVideosOverview: VideosOverviewServer): Observable { + const observables: Observable[] = [] + const videosOverviewResult: VideosOverview = { + tags: [], + categories: [], + channels: [] + } + + // Build videos objects + for (const key of Object.keys(serverVideosOverview)) { + for (const object of serverVideosOverview[ key ]) { + observables.push( + of(object.videos) + .pipe( + switchMap(videos => this.videosService.extractVideos({ total: 0, data: videos })), + map(result => result.data), + tap(videos => { + videosOverviewResult[key].push(immutableAssign(object, { videos })) + }) + ) + ) + } + } + + if (observables.length === 0) return of(videosOverviewResult) + + return forkJoin(observables) + .pipe( + // Translate categories + switchMap(() => { + return this.serverService.getServerLocale() + .pipe( + tap(translations => { + for (const c of videosOverviewResult.categories) { + c.category.label = peertubeTranslate(c.category.label, translations) + } + }) + ) + }), + map(() => videosOverviewResult) + ) + } + +} 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 @@ +

Discover

+
+ +
No results.
+ +
+ + +
+

+ {{ object.category.label }} +

+ +
+ + +
+
+ +
+

+ #{{ object.tag }} +

+ +
+ + +
+
+ + + +
+ +
+ +
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 @@ +@import '_variables'; +@import '_mixins'; +@import '_miniature'; + +.section-title { + // make the element span a full grid row within .videos grid + grid-column: 1 / -1; +} + +.margin-content { + @include fluid-videos-miniature-layout; +} + +.section { + @include miniature-rows; +} 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 @@ +import { Subject } from 'rxjs' +import { Component, OnInit } from '@angular/core' +import { Notifier, ScreenService, User, UserService } from '@app/core' +import { Video } from '@app/shared/shared-main' +import { OverviewService } from './overview.service' +import { VideosOverview } from './videos-overview.model' + +@Component({ + selector: 'my-video-overview', + templateUrl: './video-overview.component.html', + styleUrls: [ './video-overview.component.scss' ] +}) +export class VideoOverviewComponent implements OnInit { + onDataSubject = new Subject() + + overviews: VideosOverview[] = [] + notResults = false + + userMiniature: User + + private loaded = false + private currentPage = 1 + private maxPage = 20 + private lastWasEmpty = false + private isLoading = false + + constructor ( + private notifier: Notifier, + private userService: UserService, + private overviewService: OverviewService, + private screenService: ScreenService + ) { } + + ngOnInit () { + this.loadMoreResults() + + this.userService.getAnonymousOrLoggedUser() + .subscribe(user => this.userMiniature = user) + + this.userService.listenAnonymousUpdate() + .subscribe(user => this.userMiniature = user) + } + + buildVideoChannelBy (object: { videos: Video[] }) { + return object.videos[0].byVideoChannel + } + + buildVideoChannelAvatarUrl (object: { videos: Video[] }) { + return object.videos[0].videoChannelAvatarUrl + } + + buildVideos (videos: Video[]) { + const numberOfVideos = this.screenService.getNumberOfAvailableMiniatures() + + return videos.slice(0, numberOfVideos * 2) + } + + onNearOfBottom () { + if (this.currentPage >= this.maxPage) return + if (this.lastWasEmpty) return + if (this.isLoading) return + + this.currentPage++ + this.loadMoreResults() + } + + private loadMoreResults () { + this.isLoading = true + + this.overviewService.getVideosOverview(this.currentPage) + .subscribe( + overview => { + this.isLoading = false + + if (overview.tags.length === 0 && overview.channels.length === 0 && overview.categories.length === 0) { + this.lastWasEmpty = true + if (this.loaded === false) this.notResults = true + + return + } + + this.loaded = true + this.onDataSubject.next(overview) + + this.overviews.push(overview) + }, + + err => { + this.notifier.error(err.message) + this.isLoading = false + } + ) + } +} 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 @@ +import { Video } from '@app/shared/shared-main' +import { VideoChannelSummary, VideoConstant, VideosOverview as VideosOverviewServer } from '@shared/models' + +export class VideosOverview implements VideosOverviewServer { + channels: { + channel: VideoChannelSummary + videos: Video[] + }[] + + categories: { + category: VideoConstant + videos: Video[] + }[] + + tags: { + tag: string + videos: Video[] + }[] + [key: string]: any +} diff --git a/client/src/app/videos/video-list/video-local.component.ts b/client/src/app/videos/video-list/video-local.component.ts index 960523cd7..b4c71ac49 100644 --- a/client/src/app/videos/video-list/video-local.component.ts +++ b/client/src/app/videos/video-list/video-local.component.ts @@ -1,23 +1,17 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { immutableAssign } from '@app/shared/misc/utils' -import { AuthService } from '../../core/auth' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoSortField } from '../../shared/video/sort-field.type' -import { VideoService } from '../../shared/video/video.service' -import { VideoFilter } from '../../../../../shared/models/videos/video-query.type' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { ScreenService } from '@app/shared/misc/screen.service' -import { UserRight } from '../../../../../shared/models/users' -import { Notifier, ServerService } from '@app/core' +import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' -import { UserService } from '@app/shared' -import { LocalStorageService } from '@app/shared/misc/storage.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { UserRight, VideoFilter, VideoSortField } from '@shared/models' @Component({ selector: 'my-videos-local', - styleUrls: [ '../../shared/video/abstract-video-list.scss' ], - templateUrl: '../../shared/video/abstract-video-list.html' + styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ], + templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html' }) export class VideoLocalComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage: string 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 index cc91a2330..ca14851bb 100644 --- a/client/src/app/videos/video-list/video-most-liked.component.ts +++ b/client/src/app/videos/video-list/video-most-liked.component.ts @@ -1,21 +1,17 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { immutableAssign } from '@app/shared/misc/utils' -import { AuthService } from '../../core/auth' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoSortField } from '../../shared/video/sort-field.type' -import { VideoService } from '../../shared/video/video.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { ScreenService } from '@app/shared/misc/screen.service' -import { Notifier, ServerService } from '@app/core' +import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' -import { UserService } from '@app/shared' -import { LocalStorageService } from '@app/shared/misc/storage.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { VideoSortField } from '@shared/models' @Component({ selector: 'my-videos-most-liked', - styleUrls: [ '../../shared/video/abstract-video-list.scss' ], - templateUrl: '../../shared/video/abstract-video-list.html' + styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ], + templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html' }) export class VideoMostLikedComponent extends AbstractVideoList implements OnInit { titlePage: string diff --git a/client/src/app/videos/video-list/video-overview.component.html b/client/src/app/videos/video-list/video-overview.component.html deleted file mode 100644 index ca986c634..000000000 --- a/client/src/app/videos/video-list/video-overview.component.html +++ /dev/null @@ -1,52 +0,0 @@ -

Discover

-
- -
No results.
- -
- - -
-

- {{ object.category.label }} -

- -
- - -
-
- -
-

- #{{ object.tag }} -

- -
- - -
-
- - - -
- -
- -
diff --git a/client/src/app/videos/video-list/video-overview.component.scss b/client/src/app/videos/video-list/video-overview.component.scss deleted file mode 100644 index c1d10188a..000000000 --- a/client/src/app/videos/video-list/video-overview.component.scss +++ /dev/null @@ -1,16 +0,0 @@ -@import '_variables'; -@import '_mixins'; -@import '_miniature'; - -.section-title { - // make the element span a full grid row within .videos grid - grid-column: 1 / -1; -} - -.margin-content { - @include fluid-videos-miniature-layout; -} - -.section { - @include miniature-rows; -} diff --git a/client/src/app/videos/video-list/video-overview.component.ts b/client/src/app/videos/video-list/video-overview.component.ts deleted file mode 100644 index 8ff8400db..000000000 --- a/client/src/app/videos/video-list/video-overview.component.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Subject } from 'rxjs' -import { Component, OnInit } from '@angular/core' -import { Notifier } from '@app/core' -import { User, UserService } from '@app/shared' -import { ScreenService } from '@app/shared/misc/screen.service' -import { OverviewService } from '@app/shared/overview' -import { VideosOverview } from '@app/shared/overview/videos-overview.model' -import { Video } from '@app/shared/video/video.model' - -@Component({ - selector: 'my-video-overview', - templateUrl: './video-overview.component.html', - styleUrls: [ './video-overview.component.scss' ] -}) -export class VideoOverviewComponent implements OnInit { - onDataSubject = new Subject() - - overviews: VideosOverview[] = [] - notResults = false - - userMiniature: User - - private loaded = false - private currentPage = 1 - private maxPage = 20 - private lastWasEmpty = false - private isLoading = false - - constructor ( - private notifier: Notifier, - private userService: UserService, - private overviewService: OverviewService, - private screenService: ScreenService - ) { } - - ngOnInit () { - this.loadMoreResults() - - this.userService.getAnonymousOrLoggedUser() - .subscribe(user => this.userMiniature = user) - - this.userService.listenAnonymousUpdate() - .subscribe(user => this.userMiniature = user) - } - - buildVideoChannelBy (object: { videos: Video[] }) { - return object.videos[0].byVideoChannel - } - - buildVideoChannelAvatarUrl (object: { videos: Video[] }) { - return object.videos[0].videoChannelAvatarUrl - } - - buildVideos (videos: Video[]) { - const numberOfVideos = this.screenService.getNumberOfAvailableMiniatures() - - return videos.slice(0, numberOfVideos * 2) - } - - onNearOfBottom () { - if (this.currentPage >= this.maxPage) return - if (this.lastWasEmpty) return - if (this.isLoading) return - - this.currentPage++ - this.loadMoreResults() - } - - private loadMoreResults () { - this.isLoading = true - - this.overviewService.getVideosOverview(this.currentPage) - .subscribe( - overview => { - this.isLoading = false - - if (overview.tags.length === 0 && overview.channels.length === 0 && overview.categories.length === 0) { - this.lastWasEmpty = true - if (this.loaded === false) this.notResults = true - - return - } - - this.loaded = true - this.onDataSubject.next(overview) - - this.overviews.push(overview) - }, - - err => { - this.notifier.error(err.message) - this.isLoading = false - } - ) - } -} 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 index 9f57a61e3..c9395133f 100644 --- a/client/src/app/videos/video-list/video-recently-added.component.ts +++ b/client/src/app/videos/video-list/video-recently-added.component.ts @@ -1,21 +1,17 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { immutableAssign } from '@app/shared/misc/utils' -import { AuthService } from '../../core/auth' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoSortField } from '../../shared/video/sort-field.type' -import { VideoService } from '../../shared/video/video.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { ScreenService } from '@app/shared/misc/screen.service' -import { Notifier, ServerService } from '@app/core' +import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' -import { UserService } from '@app/shared' -import { LocalStorageService } from '@app/shared/misc/storage.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { VideoSortField } from '@shared/models' @Component({ selector: 'my-videos-recently-added', - styleUrls: [ '../../shared/video/abstract-video-list.scss' ], - templateUrl: '../../shared/video/abstract-video-list.html' + styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ], + templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html' }) export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage: string diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts index 62e0f4e69..10eab18de 100644 --- a/client/src/app/videos/video-list/video-trending.component.ts +++ b/client/src/app/videos/video-list/video-trending.component.ts @@ -1,21 +1,17 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { immutableAssign } from '@app/shared/misc/utils' -import { AuthService } from '../../core/auth' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoSortField } from '../../shared/video/sort-field.type' -import { VideoService } from '../../shared/video/video.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { ScreenService } from '@app/shared/misc/screen.service' -import { Notifier, ServerService } from '@app/core' +import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' -import { UserService } from '@app/shared' -import { LocalStorageService } from '@app/shared/misc/storage.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { VideoSortField } from '@shared/models' @Component({ selector: 'my-videos-trending', - styleUrls: [ '../../shared/video/abstract-video-list.scss' ], - templateUrl: '../../shared/video/abstract-video-list.html' + styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ], + templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html' }) export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage: string 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 index 036fd8dcb..41ad9b277 100644 --- a/client/src/app/videos/video-list/video-user-subscriptions.component.ts +++ b/client/src/app/videos/video-list/video-user-subscriptions.component.ts @@ -1,22 +1,18 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' -import { immutableAssign } from '@app/shared/misc/utils' -import { AuthService } from '../../core/auth' -import { AbstractVideoList } from '../../shared/video/abstract-video-list' -import { VideoSortField } from '../../shared/video/sort-field.type' -import { VideoService } from '../../shared/video/video.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { ScreenService } from '@app/shared/misc/screen.service' -import { OwnerDisplayType } from '@app/shared/video/video-miniature.component' -import { Notifier, ServerService } from '@app/core' +import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' -import { UserService } from '@app/shared' -import { LocalStorageService } from '@app/shared/misc/storage.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { UserSubscriptionService } from '@app/shared/shared-user-subscription' +import { AbstractVideoList, OwnerDisplayType } from '@app/shared/shared-video-miniature' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { VideoSortField } from '@shared/models' @Component({ selector: 'my-videos-user-subscriptions', - styleUrls: [ '../../shared/video/abstract-video-list.scss' ], - templateUrl: '../../shared/video/abstract-video-list.html' + styleUrls: [ '../../shared/shared-video-miniature/abstract-video-list.scss' ], + templateUrl: '../../shared/shared-video-miniature/abstract-video-list.html' }) export class VideoUserSubscriptionsComponent extends AbstractVideoList implements OnInit, OnDestroy { titlePage: string @@ -34,6 +30,7 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement protected userService: UserService, protected screenService: ScreenService, protected storageService: LocalStorageService, + private userSubscription: UserSubscriptionService, private videoService: VideoService, private hooks: HooksService ) { @@ -64,7 +61,7 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement } return this.hooks.wrapObsFun( - this.videoService.getUserSubscriptionVideos.bind(this.videoService), + this.userSubscription.getUserSubscriptionVideos.bind(this.userSubscription), params, 'common', 'filter:api.user-subscriptions-videos.videos.list.params', -- cgit v1.2.3