From ba5d4a849c7d7ba05f093480ae12286c4af61556 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Wed, 27 Jan 2021 17:15:21 +0100 Subject: move from trending routes to alg param --- .../edit-custom-config.component.html | 32 +++--- .../edit-custom-config.component.ts | 18 ++-- .../src/app/+videos/video-list/trending/index.ts | 4 +- .../video-list/trending/video-hot.component.ts | 85 ---------------- .../trending/video-most-liked.component.ts | 81 --------------- .../trending/video-most-viewed.component.ts | 99 ------------------ .../trending/video-trending-header.component.html | 10 +- .../trending/video-trending-header.component.ts | 67 ++++++++----- .../trending/video-trending.component.ts | 111 +++++++++++++++++++++ client/src/app/+videos/videos-routing.module.ts | 42 +------- client/src/app/+videos/videos.module.ts | 10 +- client/src/app/app.component.html | 2 +- client/src/app/app.component.ts | 4 +- client/src/app/core/core.module.ts | 3 +- client/src/app/core/routing/index.ts | 1 - client/src/app/core/routing/redirect.service.ts | 34 ++----- .../src/app/core/routing/trending-guard.service.ts | 14 --- client/src/app/core/server/server.service.ts | 12 +-- client/src/app/menu/menu.component.html | 6 +- .../video-list-header.component.ts | 10 +- 20 files changed, 225 insertions(+), 420 deletions(-) delete mode 100644 client/src/app/+videos/video-list/trending/video-hot.component.ts delete mode 100644 client/src/app/+videos/video-list/trending/video-most-liked.component.ts delete mode 100644 client/src/app/+videos/video-list/trending/video-most-viewed.component.ts create mode 100644 client/src/app/+videos/video-list/trending/video-trending.component.ts delete mode 100644 client/src/app/core/routing/trending-guard.service.ts (limited to 'client/src/app') diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html index 83b1c6a31..dd62a4aab 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html @@ -271,10 +271,9 @@ - - - - + + + @@ -283,17 +282,20 @@
{{ formErrors.instance.defaultClientRoute }}
-
- -
- -
-
{{ formErrors.instance.defaultTrendingRoute }}
+
+ + + +
+ +
+
{{ formErrors.trending.videos.algorithms.default }}
+
+
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index e6fc4582b..9a46a2e59 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts @@ -186,12 +186,6 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A languages: null, defaultClientRoute: null, - defaultTrendingRoute: null, - pages: { - hot: { - enabled: null - } - }, customizations: { javascript: null, @@ -230,6 +224,14 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A } } }, + trending: { + videos: { + algorithms: { + enabled: null, + default: null + } + } + }, admin: { email: ADMIN_EMAIL_VALIDATOR }, @@ -370,8 +372,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A return this.form.value['followings']['instance']['autoFollowIndex']['enabled'] === true } - isTrendingHotEnabled () { - return this.form.value['instance']['pages']['hot']['enabled'] === true + trendingVideosAlgorithmsEnabledIncludes (algorithm: string) { + return this.form.value['trending']['videos']['algorithms']['enabled'].find((e: string) => e === algorithm) } async formValidated () { diff --git a/client/src/app/+videos/video-list/trending/index.ts b/client/src/app/+videos/video-list/trending/index.ts index 93f4b1df6..70835885a 100644 --- a/client/src/app/+videos/video-list/trending/index.ts +++ b/client/src/app/+videos/video-list/trending/index.ts @@ -1,4 +1,2 @@ export * from './video-trending-header.component' -export * from './video-hot.component' -export * from './video-most-viewed.component' -export * from './video-most-liked.component' +export * from './video-trending.component' diff --git a/client/src/app/+videos/video-list/trending/video-hot.component.ts b/client/src/app/+videos/video-list/trending/video-hot.component.ts deleted file mode 100644 index 1617eb21e..000000000 --- a/client/src/app/+videos/video-list/trending/video-hot.component.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Component, ComponentFactoryResolver, Injector, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { HooksService } from '@app/core/plugins/hooks.service' -import { immutableAssign } from '@app/helpers' -import { VideoService } from '@app/shared/shared-main' -import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { VideoSortField } from '@shared/models' -import { VideoTrendingHeaderComponent } from './video-trending-header.component' - -@Component({ - selector: 'my-videos-hot', - styleUrls: [ '../../../shared/shared-video-miniature/abstract-video-list.scss' ], - templateUrl: '../../../shared/shared-video-miniature/abstract-video-list.html' -}) -export class VideoHotComponent extends AbstractVideoList implements OnInit, OnDestroy { - HeaderComponent = VideoTrendingHeaderComponent - titlePage: string - defaultSort: VideoSortField = '-hot' - - useUserVideoPreferences = true - - constructor ( - protected router: Router, - protected serverService: ServerService, - protected route: ActivatedRoute, - protected notifier: Notifier, - protected authService: AuthService, - protected userService: UserService, - protected screenService: ScreenService, - protected storageService: LocalStorageService, - protected cfr: ComponentFactoryResolver, - private videoService: VideoService, - private hooks: HooksService - ) { - super() - - this.headerComponentInjector = this.getInjector() - } - - ngOnInit () { - super.ngOnInit() - - this.generateSyndicationList() - } - - ngOnDestroy () { - super.ngOnDestroy() - } - - getVideosObservable (page: number) { - const newPagination = immutableAssign(this.pagination, { currentPage: page }) - const params = { - videoPagination: newPagination, - sort: this.sort, - categoryOneOf: this.categoryOneOf, - languageOneOf: this.languageOneOf, - nsfwPolicy: this.nsfwPolicy, - skipCount: true - } - - return this.hooks.wrapObsFun( - this.videoService.getVideos.bind(this.videoService), - params, - 'common', - 'filter:api.trending-videos.videos.list.params', - 'filter:api.trending-videos.videos.list.result' - ) - } - - generateSyndicationList () { - this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf) - } - - getInjector () { - return Injector.create({ - providers: [{ - provide: 'data', - useValue: { - model: this.defaultSort - } - }] - }) - } -} diff --git a/client/src/app/+videos/video-list/trending/video-most-liked.component.ts b/client/src/app/+videos/video-list/trending/video-most-liked.component.ts deleted file mode 100644 index 1781cc6aa..000000000 --- a/client/src/app/+videos/video-list/trending/video-most-liked.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Component, ComponentFactoryResolver, Injector, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { HooksService } from '@app/core/plugins/hooks.service' -import { immutableAssign } from '@app/helpers' -import { VideoService } from '@app/shared/shared-main' -import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { VideoSortField } from '@shared/models' -import { VideoTrendingHeaderComponent } from './video-trending-header.component' - -@Component({ - selector: 'my-videos-most-liked', - 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 { - HeaderComponent = VideoTrendingHeaderComponent - titlePage: string - defaultSort: VideoSortField = '-likes' - - useUserVideoPreferences = true - - constructor ( - protected router: Router, - protected serverService: ServerService, - protected route: ActivatedRoute, - protected notifier: Notifier, - protected authService: AuthService, - protected userService: UserService, - protected screenService: ScreenService, - protected storageService: LocalStorageService, - protected cfr: ComponentFactoryResolver, - private videoService: VideoService, - private hooks: HooksService - ) { - super() - - this.headerComponentInjector = this.getInjector() - } - - ngOnInit () { - super.ngOnInit() - - this.generateSyndicationList() - } - - getVideosObservable (page: number) { - const newPagination = immutableAssign(this.pagination, { currentPage: page }) - const params = { - videoPagination: newPagination, - sort: this.sort, - categoryOneOf: this.categoryOneOf, - languageOneOf: this.languageOneOf, - nsfwPolicy: this.nsfwPolicy, - skipCount: true - } - - return this.hooks.wrapObsFun( - this.videoService.getVideos.bind(this.videoService), - params, - 'common', - 'filter:api.most-liked-videos.videos.list.params', - 'filter:api.most-liked-videos.videos.list.result' - ) - } - - generateSyndicationList () { - this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf) - } - - getInjector () { - return Injector.create({ - providers: [{ - provide: 'data', - useValue: { - model: this.defaultSort - } - }] - }) - } -} diff --git a/client/src/app/+videos/video-list/trending/video-most-viewed.component.ts b/client/src/app/+videos/video-list/trending/video-most-viewed.component.ts deleted file mode 100644 index 98ced42d6..000000000 --- a/client/src/app/+videos/video-list/trending/video-most-viewed.component.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Component, ComponentFactoryResolver, Injector, OnDestroy, OnInit } from '@angular/core' -import { ActivatedRoute, Router } from '@angular/router' -import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { HooksService } from '@app/core/plugins/hooks.service' -import { immutableAssign } from '@app/helpers' -import { VideoService } from '@app/shared/shared-main' -import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { VideoSortField } from '@shared/models' -import { VideoTrendingHeaderComponent } from './video-trending-header.component' - -@Component({ - selector: 'my-videos-most-viewed', - styleUrls: [ '../../../shared/shared-video-miniature/abstract-video-list.scss' ], - templateUrl: '../../../shared/shared-video-miniature/abstract-video-list.html' -}) -export class VideoMostViewedComponent extends AbstractVideoList implements OnInit, OnDestroy { - HeaderComponent = VideoTrendingHeaderComponent - titlePage: string - defaultSort: VideoSortField = '-trending' - - useUserVideoPreferences = true - - constructor ( - protected router: Router, - protected serverService: ServerService, - protected route: ActivatedRoute, - protected notifier: Notifier, - protected authService: AuthService, - protected userService: UserService, - protected screenService: ScreenService, - protected storageService: LocalStorageService, - protected cfr: ComponentFactoryResolver, - private videoService: VideoService, - private hooks: HooksService - ) { - super() - - this.headerComponentInjector = this.getInjector() - } - - ngOnInit () { - super.ngOnInit() - - this.generateSyndicationList() - - this.serverService.getConfig().subscribe( - config => { - const trendingDays = config.trending.videos.intervalDays - - if (trendingDays === 1) { - this.titleTooltip = $localize`Trending videos are those totalizing the greatest number of views during the last 24 hours` - } else { - this.titleTooltip = $localize`Trending videos are those totalizing the greatest number of views during the last ${trendingDays} days` - } - - this.headerComponentInjector = this.getInjector() - this.setHeader() - }) - } - - ngOnDestroy () { - super.ngOnDestroy() - } - - getVideosObservable (page: number) { - const newPagination = immutableAssign(this.pagination, { currentPage: page }) - const params = { - videoPagination: newPagination, - sort: this.sort, - categoryOneOf: this.categoryOneOf, - languageOneOf: this.languageOneOf, - nsfwPolicy: this.nsfwPolicy, - skipCount: true - } - - return this.hooks.wrapObsFun( - this.videoService.getVideos.bind(this.videoService), - params, - 'common', - 'filter:api.trending-videos.videos.list.params', - 'filter:api.trending-videos.videos.list.result' - ) - } - - generateSyndicationList () { - this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf) - } - - getInjector () { - return Injector.create({ - providers: [{ - provide: 'data', - useValue: { - model: this.defaultSort - } - }] - }) - } -} diff --git a/client/src/app/+videos/video-list/trending/video-trending-header.component.html b/client/src/app/+videos/video-list/trending/video-trending-header.component.html index a025bf1a2..7eb1e4f95 100644 --- a/client/src/app/+videos/video-list/trending/video-trending-header.component.html +++ b/client/src/app/+videos/video-list/trending/video-trending-header.component.html @@ -1,6 +1,8 @@
- + + +
\ No newline at end of file diff --git a/client/src/app/+videos/video-list/trending/video-trending-header.component.ts b/client/src/app/+videos/video-list/trending/video-trending-header.component.ts index e49b61c68..33eaa2c1e 100644 --- a/client/src/app/+videos/video-list/trending/video-trending-header.component.ts +++ b/client/src/app/+videos/video-list/trending/video-trending-header.component.ts @@ -1,30 +1,34 @@ -import { Component, Inject, OnInit } from '@angular/core' -import { Router } from '@angular/router' +import { Component, HostBinding, Inject, OnDestroy, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' import { VideoListHeaderComponent } from '@app/shared/shared-video-miniature' import { GlobalIconName } from '@app/shared/shared-icons' -import { VideoSortField } from '@shared/models' import { ServerService } from '@app/core/server/server.service' +import { Subscription } from 'rxjs' +import { RedirectService } from '@app/core' interface VideoTrendingHeaderItem { label: string iconName: GlobalIconName - value: VideoSortField - path: string + value: string tooltip?: string hidden?: boolean } @Component({ selector: 'video-trending-title-page', - host: { 'class': 'title-page title-page-single' }, styleUrls: [ './video-trending-header.component.scss' ], templateUrl: './video-trending-header.component.html' }) -export class VideoTrendingHeaderComponent extends VideoListHeaderComponent implements OnInit { +export class VideoTrendingHeaderComponent extends VideoListHeaderComponent implements OnInit, OnDestroy { + @HostBinding('class') class = 'title-page title-page-single' + buttons: VideoTrendingHeaderItem[] + private algorithmChangeSub: Subscription + constructor ( @Inject('data') public data: any, + private route: ActivatedRoute, private router: Router, private serverService: ServerService ) { @@ -34,23 +38,20 @@ export class VideoTrendingHeaderComponent extends VideoListHeaderComponent imple { label: $localize`:A variant of Trending videos based on the number of recent interactions:Hot`, iconName: 'flame', - value: '-hot', - path: 'hot', + value: 'hot', tooltip: $localize`Videos totalizing the most interactions for recent videos`, hidden: true }, { label: $localize`:Main variant of Trending videos based on number of recent views:Views`, iconName: 'trending', - value: '-trending', - path: 'most-viewed', - tooltip: $localize`Videos totalizing the most views during the last 24 hours`, + value: 'most-viewed', + tooltip: $localize`Videos totalizing the most views during the last 24 hours` }, { label: $localize`:A variant of Trending videos based on the number of likes:Likes`, iconName: 'like', - value: '-likes', - path: 'most-liked', + value: 'most-liked', tooltip: $localize`Videos that have the most likes` } ] @@ -59,20 +60,40 @@ export class VideoTrendingHeaderComponent extends VideoListHeaderComponent imple ngOnInit () { this.serverService.getConfig() .subscribe(config => { - // don't filter if auto-blacklist is not enabled as this will be the only list - if (config.instance.pages.hot.enabled) { - const index = this.buttons.findIndex(b => b.path === 'hot') - this.buttons[index].hidden = false - } + this.buttons = this.buttons.map(b => { + b.hidden = !config.trending.videos.algorithms.enabled.includes(b.value) + return b + }) }) + + this.algorithmChangeSub = this.route.queryParams.subscribe( + queryParams => { + const algorithm = queryParams['alg'] + if (algorithm) { + this.data.model = algorithm + } else { + this.data.model = RedirectService.DEFAULT_TRENDING_ALGORITHM + } + } + ) } - get visibleButtons () { - return this.buttons.filter(b => !b.hidden) + ngOnDestroy () { + if (this.algorithmChangeSub) this.algorithmChangeSub.unsubscribe() } setSort () { - const path = this.buttons.find(b => b.value === this.data.model).path - this.router.navigate([ `/videos/${path}` ]) + const alg = this.data.model !== RedirectService.DEFAULT_TRENDING_ALGORITHM + ? this.data.model + : undefined + + this.router.navigate( + [], + { + relativeTo: this.route, + queryParams: { alg }, + queryParamsHandling: 'merge' + } + ) } } diff --git a/client/src/app/+videos/video-list/trending/video-trending.component.ts b/client/src/app/+videos/video-list/trending/video-trending.component.ts new file mode 100644 index 000000000..6128c4acd --- /dev/null +++ b/client/src/app/+videos/video-list/trending/video-trending.component.ts @@ -0,0 +1,111 @@ +import { Component, ComponentFactoryResolver, Injector, OnDestroy, OnInit } from '@angular/core' +import { ActivatedRoute, Router } from '@angular/router' +import { AuthService, LocalStorageService, Notifier, RedirectService, ScreenService, ServerService, UserService } from '@app/core' +import { HooksService } from '@app/core/plugins/hooks.service' +import { immutableAssign } from '@app/helpers' +import { VideoService } from '@app/shared/shared-main' +import { AbstractVideoList } from '@app/shared/shared-video-miniature' +import { VideoSortField } from '@shared/models' +import { Subscription } from 'rxjs' +import { VideoTrendingHeaderComponent } from './video-trending-header.component' + +@Component({ + selector: 'my-videos-hot', + 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 { + HeaderComponent = VideoTrendingHeaderComponent + titlePage: string + defaultSort: VideoSortField = '-trending' + + useUserVideoPreferences = true + + private algorithmChangeSub: Subscription + + constructor ( + protected router: Router, + protected serverService: ServerService, + protected route: ActivatedRoute, + protected notifier: Notifier, + protected authService: AuthService, + protected userService: UserService, + protected screenService: ScreenService, + protected storageService: LocalStorageService, + protected cfr: ComponentFactoryResolver, + private videoService: VideoService, + private hooks: HooksService + ) { + super() + + this.defaultSort = this.parseAlgorithm(RedirectService.DEFAULT_TRENDING_ALGORITHM) + + this.headerComponentInjector = this.getInjector() + } + + ngOnInit () { + super.ngOnInit() + + this.generateSyndicationList() + + this.algorithmChangeSub = this.route.queryParams.subscribe( + queryParams => { + const algorithm = queryParams['alg'] || RedirectService.DEFAULT_TRENDING_ALGORITHM + + this.sort = this.parseAlgorithm(algorithm) + this.reloadVideos() + } + ) + } + + ngOnDestroy () { + super.ngOnDestroy() + if (this.algorithmChangeSub) this.algorithmChangeSub.unsubscribe() + } + + getVideosObservable (page: number) { + const newPagination = immutableAssign(this.pagination, { currentPage: page }) + const params = { + videoPagination: newPagination, + sort: this.sort, + categoryOneOf: this.categoryOneOf, + languageOneOf: this.languageOneOf, + nsfwPolicy: this.nsfwPolicy, + skipCount: true + } + + return this.hooks.wrapObsFun( + this.videoService.getVideos.bind(this.videoService), + params, + 'common', + 'filter:api.trending-videos.videos.list.params', + 'filter:api.trending-videos.videos.list.result' + ) + } + + generateSyndicationList () { + this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, undefined, this.categoryOneOf) + } + + getInjector () { + return Injector.create({ + providers: [{ + provide: 'data', + useValue: { + model: this.defaultSort + } + }] + }) + } + + private parseAlgorithm (algorithm: string): VideoSortField { + switch (algorithm) { + case 'most-viewed': + return '-trending' + case 'most-liked': + return '-likes' + default: + return '-' + algorithm as VideoSortField + } + } +} diff --git a/client/src/app/+videos/videos-routing.module.ts b/client/src/app/+videos/videos-routing.module.ts index 973935af8..16e3b9bb2 100644 --- a/client/src/app/+videos/videos-routing.module.ts +++ b/client/src/app/+videos/videos-routing.module.ts @@ -1,11 +1,9 @@ import { NgModule } from '@angular/core' import { RouterModule, Routes } from '@angular/router' -import { LoginGuard, TrendingGuard } from '@app/core' +import { LoginGuard } from '@app/core' import { MetaGuard } from '@ngx-meta/core' +import { VideoTrendingComponent } from './video-list' import { VideoOverviewComponent } from './video-list/overview/video-overview.component' -import { VideoHotComponent } from './video-list/trending/video-hot.component' -import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' -import { VideoMostViewedComponent } from './video-list/trending/video-most-viewed.component' import { VideoLocalComponent } from './video-list/video-local.component' import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' import { VideoUserSubscriptionsComponent } from './video-list/video-user-subscriptions.component' @@ -28,46 +26,16 @@ const videosRoutes: Routes = [ }, { path: 'trending', - canActivate: [ TrendingGuard ] - }, - { - path: 'hot', - component: VideoHotComponent, + component: VideoTrendingComponent, data: { meta: { - title: $localize`Hot videos` - }, - reuse: { - enabled: true, - key: 'hot-videos-list' - } - } - }, - { - path: 'most-viewed', - component: VideoMostViewedComponent, - data: { - meta: { - title: $localize`Most viewed videos` - }, - reuse: { - enabled: true, - key: 'most-viewed-videos-list' + title: $localize`Trending videos` } } }, { path: 'most-liked', - component: VideoMostLikedComponent, - data: { - meta: { - title: $localize`Most liked videos` - }, - reuse: { - enabled: true, - key: 'most-liked-videos-list' - } - } + redirectTo: 'trending?alg=most-liked' }, { path: 'recently-added', diff --git a/client/src/app/+videos/videos.module.ts b/client/src/app/+videos/videos.module.ts index ae9c680eb..61d012d63 100644 --- a/client/src/app/+videos/videos.module.ts +++ b/client/src/app/+videos/videos.module.ts @@ -1,16 +1,12 @@ -import { CommonModule } from '@angular/common' import { NgModule } from '@angular/core' import { SharedFormModule } from '@app/shared/shared-forms' import { SharedGlobalIconModule } from '@app/shared/shared-icons' import { SharedMainModule } from '@app/shared/shared-main' import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription' import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' -import { OverviewService } from './video-list' +import { OverviewService, VideoTrendingComponent } from './video-list' import { VideoOverviewComponent } from './video-list/overview/video-overview.component' import { VideoTrendingHeaderComponent } from './video-list/trending/video-trending-header.component' -import { VideoHotComponent } from './video-list/trending/video-hot.component' -import { VideoMostViewedComponent } from './video-list/trending/video-most-viewed.component' -import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' import { VideoLocalComponent } from './video-list/video-local.component' import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' import { VideoUserSubscriptionsComponent } from './video-list/video-user-subscriptions.component' @@ -32,9 +28,7 @@ import { VideosComponent } from './videos.component' VideosComponent, VideoTrendingHeaderComponent, - VideoMostViewedComponent, - VideoHotComponent, - VideoMostLikedComponent, + VideoTrendingComponent, VideoRecentlyAddedComponent, VideoLocalComponent, VideoUserSubscriptionsComponent, diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html index 77d876f8e..108b127be 100644 --- a/client/src/app/app.component.html +++ b/client/src/app/app.component.html @@ -8,7 +8,7 @@
- + {{ instanceName }} diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index ca4b69899..66d871b4a 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts @@ -66,8 +66,8 @@ export class AppComponent implements OnInit, AfterViewInit { return this.serverConfig.instance.name } - get defaultRoute () { - return RedirectService.DEFAULT_ROUTE + goToDefaultRoute () { + return this.router.navigateByUrl(RedirectService.DEFAULT_ROUTE) } ngOnInit () { diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts index 32dfc8f36..2392a234c 100644 --- a/client/src/app/core/core.module.ts +++ b/client/src/app/core/core.module.ts @@ -15,7 +15,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard' import { Notifier } from './notification' import { HtmlRendererService, LinkifierService, MarkdownService } from './renderer' import { RestExtractor, RestService } from './rest' -import { LoginGuard, RedirectService, UserRightGuard, UnloggedGuard, TrendingGuard } from './routing' +import { LoginGuard, RedirectService, UserRightGuard, UnloggedGuard } from './routing' import { CanDeactivateGuard } from './routing/can-deactivate-guard.service' import { ServerConfigResolver } from './routing/server-config-resolver.service' import { ScopedTokensService } from './scoped-tokens' @@ -56,7 +56,6 @@ import { LocalStorageService, ScreenService, SessionStorageService } from './wra LoginGuard, UserRightGuard, UnloggedGuard, - TrendingGuard, PluginService, HooksService, diff --git a/client/src/app/core/routing/index.ts b/client/src/app/core/routing/index.ts index b3985d870..239c27caf 100644 --- a/client/src/app/core/routing/index.ts +++ b/client/src/app/core/routing/index.ts @@ -8,4 +8,3 @@ export * from './redirect.service' export * from './server-config-resolver.service' export * from './unlogged-guard.service' export * from './user-right-guard.service' -export * from './trending-guard.service' diff --git a/client/src/app/core/routing/redirect.service.ts b/client/src/app/core/routing/redirect.service.ts index 76e28e461..6d26fb504 100644 --- a/client/src/app/core/routing/redirect.service.ts +++ b/client/src/app/core/routing/redirect.service.ts @@ -7,14 +7,13 @@ export class RedirectService { // Default route could change according to the instance configuration static INIT_DEFAULT_ROUTE = '/videos/trending' static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE - static INIT_DEFAULT_TRENDING_ROUTE = '/videos/most-viewed' - static DEFAULT_TRENDING_ROUTE = RedirectService.INIT_DEFAULT_TRENDING_ROUTE + static INIT_DEFAULT_TRENDING_ALGORITHM = 'most-viewed' + static DEFAULT_TRENDING_ALGORITHM = RedirectService.INIT_DEFAULT_TRENDING_ALGORITHM private previousUrl: string private currentUrl: string private redirectingToHomepage = false - private redirectingToTrending = false constructor ( private router: Router, @@ -22,27 +21,25 @@ export class RedirectService { ) { // The config is first loaded from the cache so try to get the default route const tmpConfig = this.serverService.getTmpConfig() - if (tmpConfig && tmpConfig.instance) { - if (tmpConfig.instance.defaultClientRoute) { - RedirectService.DEFAULT_ROUTE = tmpConfig.instance.defaultClientRoute - } - if (tmpConfig.instance.defaultTrendingRoute) { - RedirectService.DEFAULT_TRENDING_ROUTE = tmpConfig.instance.defaultTrendingRoute - } + if (tmpConfig?.instance?.defaultClientRoute) { + RedirectService.DEFAULT_ROUTE = tmpConfig.instance.defaultClientRoute + } + if (tmpConfig?.trending?.videos?.algorithms?.default) { + RedirectService.DEFAULT_TRENDING_ALGORITHM = tmpConfig.trending.videos.algorithms.default } // Load default route this.serverService.getConfig() .subscribe(config => { const defaultRouteConfig = config.instance.defaultClientRoute - const defaultTrendingConfig = config.instance.defaultTrendingRoute + const defaultTrendingConfig = config.trending.videos.algorithms.default if (defaultRouteConfig) { RedirectService.DEFAULT_ROUTE = defaultRouteConfig } if (defaultTrendingConfig) { - RedirectService.DEFAULT_TRENDING_ROUTE = defaultTrendingConfig + RedirectService.DEFAULT_TRENDING_ALGORITHM = defaultTrendingConfig } }) @@ -70,15 +67,6 @@ export class RedirectService { return this.redirectToHomepage() } - redirectToTrending () { - if (this.redirectingToTrending) return - - this.redirectingToTrending = true - - this.router.navigate([ RedirectService.DEFAULT_TRENDING_ROUTE ]) - .then(() => this.redirectingToTrending = false) - } - redirectToHomepage (skipLocationChange = false) { if (this.redirectingToHomepage) return @@ -86,7 +74,7 @@ export class RedirectService { console.log('Redirecting to %s...', RedirectService.DEFAULT_ROUTE) - this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { skipLocationChange }) + this.router.navigateByUrl(RedirectService.DEFAULT_ROUTE, { skipLocationChange }) .then(() => this.redirectingToHomepage = false) .catch(() => { this.redirectingToHomepage = false @@ -98,7 +86,7 @@ export class RedirectService { ) RedirectService.DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE - return this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { skipLocationChange }) + return this.router.navigateByUrl(RedirectService.DEFAULT_ROUTE, { skipLocationChange }) }) } diff --git a/client/src/app/core/routing/trending-guard.service.ts b/client/src/app/core/routing/trending-guard.service.ts deleted file mode 100644 index 7db7fe994..000000000 --- a/client/src/app/core/routing/trending-guard.service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Injectable } from '@angular/core' -import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router' -import { RedirectService } from './redirect.service' - -@Injectable() -export class TrendingGuard implements CanActivate { - - constructor (private redirectService: RedirectService) {} - - canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { - this.redirectService.redirectToTrending() - return false - } -} diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index 5f13190b4..a38883eee 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts @@ -39,12 +39,6 @@ export class ServerService { isNSFW: false, defaultNSFWPolicy: 'do_not_list' as 'do_not_list', defaultClientRoute: '', - defaultTrendingRoute: '', - pages: { - hot: { - enabled: true - } - }, customizations: { javascript: '', css: '' @@ -131,7 +125,11 @@ export class ServerService { }, trending: { videos: { - intervalDays: 0 + intervalDays: 0, + algorithms: { + enabled: [ 'hot', 'most-viewed', 'most-liked' ], + default: 'most-viewed' + } } }, autoBlacklist: { diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index fc57b970b..9aa397edd 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html @@ -127,14 +127,10 @@ Discover - + Trending - - - - diff --git a/client/src/app/shared/shared-video-miniature/video-list-header.component.ts b/client/src/app/shared/shared-video-miniature/video-list-header.component.ts index 67bbf7d7a..08a961be1 100644 --- a/client/src/app/shared/shared-video-miniature/video-list-header.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-list-header.component.ts @@ -1,16 +1,22 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core' +export interface GenericHeaderData { + titlePage: string + titleTooltip?: string +} + export abstract class GenericHeaderComponent { - constructor (@Inject('data') public data: any) {} + constructor (@Inject('data') public data: GenericHeaderData) {} } @Component({ selector: 'my-video-list-header', + // tslint:disable-next-line:use-component-view-encapsulation encapsulation: ViewEncapsulation.None, templateUrl: './video-list-header.component.html' }) export class VideoListHeaderComponent extends GenericHeaderComponent { - constructor (@Inject('data') public data: any) { + constructor (@Inject('data') public data: GenericHeaderData) { super(data) } } -- cgit v1.2.3