diff options
Diffstat (limited to 'client/src/app')
17 files changed, 136 insertions, 38 deletions
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 9e4691670..83b1c6a31 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 | |||
@@ -269,9 +269,13 @@ | |||
269 | <div class="peertube-select-container"> | 269 | <div class="peertube-select-container"> |
270 | <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute" class="form-control"> | 270 | <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute" class="form-control"> |
271 | <option i18n value="/videos/overview">Discover videos</option> | 271 | <option i18n value="/videos/overview">Discover videos</option> |
272 | <option i18n value="/videos/trending">Trending videos</option> | 272 | <optgroup i18n-label label="Trending pages"> |
273 | <option i18n value="/videos/hot">Hot videos</option> | 273 | <option i18n value="/videos/trending">Default trending page</option> |
274 | <option i18n value="/videos/most-liked">Most liked videos</option> | 274 | <option i18n value="/videos/hot" *ngIf="isTrendingHotEnabled()">Hot videos</option> |
275 | <option i18n value="/videos/hot" *ngIf="!isTrendingHotEnabled()" disabled>Hot videos</option> | ||
276 | <option i18n value="/videos/most-viewed">Most viewed videos</option> | ||
277 | <option i18n value="/videos/most-liked">Most liked videos</option> | ||
278 | </optgroup> | ||
275 | <option i18n value="/videos/recently-added">Recently added videos</option> | 279 | <option i18n value="/videos/recently-added">Recently added videos</option> |
276 | <option i18n value="/videos/local">Local videos</option> | 280 | <option i18n value="/videos/local">Local videos</option> |
277 | </select> | 281 | </select> |
@@ -279,6 +283,19 @@ | |||
279 | <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div> | 283 | <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div> |
280 | </div> | 284 | </div> |
281 | 285 | ||
286 | <div class="form-group" formGroupName="instance"> | ||
287 | <label i18n for="instanceDefaultTrendingRoute">Default trending page</label> | ||
288 | <div class="peertube-select-container"> | ||
289 | <select id="instanceDefaultTrendingRoute" formControlName="defaultTrendingRoute" class="form-control"> | ||
290 | <option i18n value="/videos/hot" *ngIf="isTrendingHotEnabled()">Hot videos</option> | ||
291 | <option i18n value="/videos/hot" *ngIf="!isTrendingHotEnabled()" disabled>Hot videos</option> | ||
292 | <option i18n value="/videos/trending">Most viewed videos</option> | ||
293 | <option i18n value="/videos/most-liked">Most liked videos</option> | ||
294 | </select> | ||
295 | </div> | ||
296 | <div *ngIf="formErrors.instance.defaultTrendingRoute" class="form-error">{{ formErrors.instance.defaultTrendingRoute }}</div> | ||
297 | </div> | ||
298 | |||
282 | </div> | 299 | </div> |
283 | </div> | 300 | </div> |
284 | 301 | ||
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 330ab075a..e6fc4582b 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,6 +186,12 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
186 | languages: null, | 186 | languages: null, |
187 | 187 | ||
188 | defaultClientRoute: null, | 188 | defaultClientRoute: null, |
189 | defaultTrendingRoute: null, | ||
190 | pages: { | ||
191 | hot: { | ||
192 | enabled: null | ||
193 | } | ||
194 | }, | ||
189 | 195 | ||
190 | customizations: { | 196 | customizations: { |
191 | javascript: null, | 197 | javascript: null, |
@@ -364,6 +370,10 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
364 | return this.form.value['followings']['instance']['autoFollowIndex']['enabled'] === true | 370 | return this.form.value['followings']['instance']['autoFollowIndex']['enabled'] === true |
365 | } | 371 | } |
366 | 372 | ||
373 | isTrendingHotEnabled () { | ||
374 | return this.form.value['instance']['pages']['hot']['enabled'] === true | ||
375 | } | ||
376 | |||
367 | async formValidated () { | 377 | async formValidated () { |
368 | const value: CustomConfig = this.form.getRawValue() | 378 | const value: CustomConfig = this.form.getRawValue() |
369 | 379 | ||
diff --git a/client/src/app/+videos/video-list/trending/index.ts b/client/src/app/+videos/video-list/trending/index.ts index 8bae205a5..93f4b1df6 100644 --- a/client/src/app/+videos/video-list/trending/index.ts +++ b/client/src/app/+videos/video-list/trending/index.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | export * from './video-trending-header.component' | 1 | export * from './video-trending-header.component' |
2 | export * from './video-trending.component' | ||
3 | export * from './video-hot.component' | 2 | export * from './video-hot.component' |
3 | export * from './video-most-viewed.component' | ||
4 | export * from './video-most-liked.component' | 4 | export * from './video-most-liked.component' |
diff --git a/client/src/app/+videos/video-list/trending/video-trending.component.ts b/client/src/app/+videos/video-list/trending/video-most-viewed.component.ts index e77231586..98ced42d6 100644 --- a/client/src/app/+videos/video-list/trending/video-trending.component.ts +++ b/client/src/app/+videos/video-list/trending/video-most-viewed.component.ts | |||
@@ -9,11 +9,11 @@ import { VideoSortField } from '@shared/models' | |||
9 | import { VideoTrendingHeaderComponent } from './video-trending-header.component' | 9 | import { VideoTrendingHeaderComponent } from './video-trending-header.component' |
10 | 10 | ||
11 | @Component({ | 11 | @Component({ |
12 | selector: 'my-videos-trending', | 12 | selector: 'my-videos-most-viewed', |
13 | styleUrls: [ '../../../shared/shared-video-miniature/abstract-video-list.scss' ], | 13 | styleUrls: [ '../../../shared/shared-video-miniature/abstract-video-list.scss' ], |
14 | templateUrl: '../../../shared/shared-video-miniature/abstract-video-list.html' | 14 | templateUrl: '../../../shared/shared-video-miniature/abstract-video-list.html' |
15 | }) | 15 | }) |
16 | export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { | 16 | export class VideoMostViewedComponent extends AbstractVideoList implements OnInit, OnDestroy { |
17 | HeaderComponent = VideoTrendingHeaderComponent | 17 | HeaderComponent = VideoTrendingHeaderComponent |
18 | titlePage: string | 18 | titlePage: string |
19 | defaultSort: VideoSortField = '-trending' | 19 | defaultSort: VideoSortField = '-trending' |
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 6319ee6d3..a025bf1a2 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,5 +1,5 @@ | |||
1 | <div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" [(ngModel)]="data.model" (ngModelChange)="setSort()"> | 1 | <div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" [(ngModel)]="data.model" (ngModelChange)="setSort()"> |
2 | <label *ngFor="let button of buttons" ngbButtonLabel class="btn-light" placement="bottom" [ngbTooltip]="button.tooltip" container="body"> | 2 | <label *ngFor="let button of visibleButtons" ngbButtonLabel class="btn-light" placement="bottom" [ngbTooltip]="button.tooltip" container="body"> |
3 | <my-global-icon [iconName]="button.iconName"></my-global-icon> | 3 | <my-global-icon [iconName]="button.iconName"></my-global-icon> |
4 | <input ngbButton type="radio" [value]="button.value"> {{ button.label }} | 4 | <input ngbButton type="radio" [value]="button.value"> {{ button.label }} |
5 | </label> | 5 | </label> |
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 125f14e33..e49b61c68 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,8 +1,9 @@ | |||
1 | import { Component, Inject } from '@angular/core' | 1 | import { Component, Inject, OnInit } from '@angular/core' |
2 | import { Router } from '@angular/router' | 2 | import { Router } from '@angular/router' |
3 | import { VideoListHeaderComponent } from '@app/shared/shared-video-miniature' | 3 | import { VideoListHeaderComponent } from '@app/shared/shared-video-miniature' |
4 | import { GlobalIconName } from '@app/shared/shared-icons' | 4 | import { GlobalIconName } from '@app/shared/shared-icons' |
5 | import { VideoSortField } from '@shared/models' | 5 | import { VideoSortField } from '@shared/models' |
6 | import { ServerService } from '@app/core/server/server.service' | ||
6 | 7 | ||
7 | interface VideoTrendingHeaderItem { | 8 | interface VideoTrendingHeaderItem { |
8 | label: string | 9 | label: string |
@@ -10,6 +11,7 @@ interface VideoTrendingHeaderItem { | |||
10 | value: VideoSortField | 11 | value: VideoSortField |
11 | path: string | 12 | path: string |
12 | tooltip?: string | 13 | tooltip?: string |
14 | hidden?: boolean | ||
13 | } | 15 | } |
14 | 16 | ||
15 | @Component({ | 17 | @Component({ |
@@ -18,12 +20,13 @@ interface VideoTrendingHeaderItem { | |||
18 | styleUrls: [ './video-trending-header.component.scss' ], | 20 | styleUrls: [ './video-trending-header.component.scss' ], |
19 | templateUrl: './video-trending-header.component.html' | 21 | templateUrl: './video-trending-header.component.html' |
20 | }) | 22 | }) |
21 | export class VideoTrendingHeaderComponent extends VideoListHeaderComponent { | 23 | export class VideoTrendingHeaderComponent extends VideoListHeaderComponent implements OnInit { |
22 | buttons: VideoTrendingHeaderItem[] | 24 | buttons: VideoTrendingHeaderItem[] |
23 | 25 | ||
24 | constructor ( | 26 | constructor ( |
25 | @Inject('data') public data: any, | 27 | @Inject('data') public data: any, |
26 | private router: Router | 28 | private router: Router, |
29 | private serverService: ServerService | ||
27 | ) { | 30 | ) { |
28 | super(data) | 31 | super(data) |
29 | 32 | ||
@@ -34,16 +37,17 @@ export class VideoTrendingHeaderComponent extends VideoListHeaderComponent { | |||
34 | value: '-hot', | 37 | value: '-hot', |
35 | path: 'hot', | 38 | path: 'hot', |
36 | tooltip: $localize`Videos totalizing the most interactions for recent videos`, | 39 | tooltip: $localize`Videos totalizing the most interactions for recent videos`, |
40 | hidden: true | ||
37 | }, | 41 | }, |
38 | { | 42 | { |
39 | label: $localize`:Main variant of Trending videos based on number of recent views:Views`, | 43 | label: $localize`:Main variant of Trending videos based on number of recent views:Views`, |
40 | iconName: 'trending', | 44 | iconName: 'trending', |
41 | value: '-trending', | 45 | value: '-trending', |
42 | path: 'trending', | 46 | path: 'most-viewed', |
43 | tooltip: $localize`Videos totalizing the most views during the last 24 hours`, | 47 | tooltip: $localize`Videos totalizing the most views during the last 24 hours`, |
44 | }, | 48 | }, |
45 | { | 49 | { |
46 | label: $localize`:a variant of Trending videos based on the number of likes:Likes`, | 50 | label: $localize`:A variant of Trending videos based on the number of likes:Likes`, |
47 | iconName: 'like', | 51 | iconName: 'like', |
48 | value: '-likes', | 52 | value: '-likes', |
49 | path: 'most-liked', | 53 | path: 'most-liked', |
@@ -52,6 +56,21 @@ export class VideoTrendingHeaderComponent extends VideoListHeaderComponent { | |||
52 | ] | 56 | ] |
53 | } | 57 | } |
54 | 58 | ||
59 | ngOnInit () { | ||
60 | this.serverService.getConfig() | ||
61 | .subscribe(config => { | ||
62 | // don't filter if auto-blacklist is not enabled as this will be the only list | ||
63 | if (config.instance.pages.hot.enabled) { | ||
64 | const index = this.buttons.findIndex(b => b.path === 'hot') | ||
65 | this.buttons[index].hidden = false | ||
66 | } | ||
67 | }) | ||
68 | } | ||
69 | |||
70 | get visibleButtons () { | ||
71 | return this.buttons.filter(b => !b.hidden) | ||
72 | } | ||
73 | |||
55 | setSort () { | 74 | setSort () { |
56 | const path = this.buttons.find(b => b.value === this.data.model).path | 75 | const path = this.buttons.find(b => b.value === this.data.model).path |
57 | this.router.navigate([ `/videos/${path}` ]) | 76 | this.router.navigate([ `/videos/${path}` ]) |
diff --git a/client/src/app/+videos/videos-routing.module.ts b/client/src/app/+videos/videos-routing.module.ts index b6850b436..973935af8 100644 --- a/client/src/app/+videos/videos-routing.module.ts +++ b/client/src/app/+videos/videos-routing.module.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { NgModule } from '@angular/core' |
2 | import { RouterModule, Routes } from '@angular/router' | 2 | import { RouterModule, Routes } from '@angular/router' |
3 | import { LoginGuard } from '@app/core' | 3 | import { LoginGuard, TrendingGuard } from '@app/core' |
4 | import { MetaGuard } from '@ngx-meta/core' | 4 | import { MetaGuard } from '@ngx-meta/core' |
5 | import { VideoOverviewComponent } from './video-list/overview/video-overview.component' | 5 | import { VideoOverviewComponent } from './video-list/overview/video-overview.component' |
6 | import { VideoHotComponent } from './video-list/trending/video-hot.component' | 6 | import { VideoHotComponent } from './video-list/trending/video-hot.component' |
7 | import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' | 7 | import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' |
8 | import { VideoTrendingComponent } from './video-list/trending/video-trending.component' | 8 | import { VideoMostViewedComponent } from './video-list/trending/video-most-viewed.component' |
9 | import { VideoLocalComponent } from './video-list/video-local.component' | 9 | import { VideoLocalComponent } from './video-list/video-local.component' |
10 | import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' | 10 | import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' |
11 | import { VideoUserSubscriptionsComponent } from './video-list/video-user-subscriptions.component' | 11 | import { VideoUserSubscriptionsComponent } from './video-list/video-user-subscriptions.component' |
@@ -28,27 +28,31 @@ const videosRoutes: Routes = [ | |||
28 | }, | 28 | }, |
29 | { | 29 | { |
30 | path: 'trending', | 30 | path: 'trending', |
31 | component: VideoTrendingComponent, | 31 | canActivate: [ TrendingGuard ] |
32 | }, | ||
33 | { | ||
34 | path: 'hot', | ||
35 | component: VideoHotComponent, | ||
32 | data: { | 36 | data: { |
33 | meta: { | 37 | meta: { |
34 | title: $localize`Trending videos` | 38 | title: $localize`Hot videos` |
35 | }, | 39 | }, |
36 | reuse: { | 40 | reuse: { |
37 | enabled: true, | 41 | enabled: true, |
38 | key: 'trending-videos-list' | 42 | key: 'hot-videos-list' |
39 | } | 43 | } |
40 | } | 44 | } |
41 | }, | 45 | }, |
42 | { | 46 | { |
43 | path: 'hot', | 47 | path: 'most-viewed', |
44 | component: VideoHotComponent, | 48 | component: VideoMostViewedComponent, |
45 | data: { | 49 | data: { |
46 | meta: { | 50 | meta: { |
47 | title: $localize`Hot videos` | 51 | title: $localize`Most viewed videos` |
48 | }, | 52 | }, |
49 | reuse: { | 53 | reuse: { |
50 | enabled: true, | 54 | enabled: true, |
51 | key: 'hot-videos-list' | 55 | key: 'most-viewed-videos-list' |
52 | } | 56 | } |
53 | } | 57 | } |
54 | }, | 58 | }, |
diff --git a/client/src/app/+videos/videos.module.ts b/client/src/app/+videos/videos.module.ts index 4c88a0397..ae9c680eb 100644 --- a/client/src/app/+videos/videos.module.ts +++ b/client/src/app/+videos/videos.module.ts | |||
@@ -9,7 +9,7 @@ import { OverviewService } from './video-list' | |||
9 | import { VideoOverviewComponent } from './video-list/overview/video-overview.component' | 9 | import { VideoOverviewComponent } from './video-list/overview/video-overview.component' |
10 | import { VideoTrendingHeaderComponent } from './video-list/trending/video-trending-header.component' | 10 | import { VideoTrendingHeaderComponent } from './video-list/trending/video-trending-header.component' |
11 | import { VideoHotComponent } from './video-list/trending/video-hot.component' | 11 | import { VideoHotComponent } from './video-list/trending/video-hot.component' |
12 | import { VideoTrendingComponent } from './video-list/trending/video-trending.component' | 12 | import { VideoMostViewedComponent } from './video-list/trending/video-most-viewed.component' |
13 | import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' | 13 | import { VideoMostLikedComponent } from './video-list/trending/video-most-liked.component' |
14 | import { VideoLocalComponent } from './video-list/video-local.component' | 14 | import { VideoLocalComponent } from './video-list/video-local.component' |
15 | import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' | 15 | import { VideoRecentlyAddedComponent } from './video-list/video-recently-added.component' |
@@ -32,7 +32,7 @@ import { VideosComponent } from './videos.component' | |||
32 | VideosComponent, | 32 | VideosComponent, |
33 | 33 | ||
34 | VideoTrendingHeaderComponent, | 34 | VideoTrendingHeaderComponent, |
35 | VideoTrendingComponent, | 35 | VideoMostViewedComponent, |
36 | VideoHotComponent, | 36 | VideoHotComponent, |
37 | VideoMostLikedComponent, | 37 | VideoMostLikedComponent, |
38 | VideoRecentlyAddedComponent, | 38 | VideoRecentlyAddedComponent, |
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts index c4fc9995e..32dfc8f36 100644 --- a/client/src/app/core/core.module.ts +++ b/client/src/app/core/core.module.ts | |||
@@ -7,7 +7,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations' | |||
7 | import { PeerTubeSocket } from '@app/core/notification/peertube-socket.service' | 7 | import { PeerTubeSocket } from '@app/core/notification/peertube-socket.service' |
8 | import { HooksService } from '@app/core/plugins/hooks.service' | 8 | import { HooksService } from '@app/core/plugins/hooks.service' |
9 | import { PluginService } from '@app/core/plugins/plugin.service' | 9 | import { PluginService } from '@app/core/plugins/plugin.service' |
10 | import { UnloggedGuard } from '@app/core/routing/unlogged-guard.service' | ||
11 | import { AuthService } from './auth' | 10 | import { AuthService } from './auth' |
12 | import { ConfirmService } from './confirm' | 11 | import { ConfirmService } from './confirm' |
13 | import { CheatSheetComponent } from './hotkeys' | 12 | import { CheatSheetComponent } from './hotkeys' |
@@ -16,7 +15,7 @@ import { throwIfAlreadyLoaded } from './module-import-guard' | |||
16 | import { Notifier } from './notification' | 15 | import { Notifier } from './notification' |
17 | import { HtmlRendererService, LinkifierService, MarkdownService } from './renderer' | 16 | import { HtmlRendererService, LinkifierService, MarkdownService } from './renderer' |
18 | import { RestExtractor, RestService } from './rest' | 17 | import { RestExtractor, RestService } from './rest' |
19 | import { LoginGuard, RedirectService, UserRightGuard } from './routing' | 18 | import { LoginGuard, RedirectService, UserRightGuard, UnloggedGuard, TrendingGuard } from './routing' |
20 | import { CanDeactivateGuard } from './routing/can-deactivate-guard.service' | 19 | import { CanDeactivateGuard } from './routing/can-deactivate-guard.service' |
21 | import { ServerConfigResolver } from './routing/server-config-resolver.service' | 20 | import { ServerConfigResolver } from './routing/server-config-resolver.service' |
22 | import { ScopedTokensService } from './scoped-tokens' | 21 | import { ScopedTokensService } from './scoped-tokens' |
@@ -57,6 +56,7 @@ import { LocalStorageService, ScreenService, SessionStorageService } from './wra | |||
57 | LoginGuard, | 56 | LoginGuard, |
58 | UserRightGuard, | 57 | UserRightGuard, |
59 | UnloggedGuard, | 58 | UnloggedGuard, |
59 | TrendingGuard, | ||
60 | 60 | ||
61 | PluginService, | 61 | PluginService, |
62 | HooksService, | 62 | HooksService, |
diff --git a/client/src/app/core/routing/index.ts b/client/src/app/core/routing/index.ts index 239c27caf..b3985d870 100644 --- a/client/src/app/core/routing/index.ts +++ b/client/src/app/core/routing/index.ts | |||
@@ -8,3 +8,4 @@ export * from './redirect.service' | |||
8 | export * from './server-config-resolver.service' | 8 | export * from './server-config-resolver.service' |
9 | export * from './unlogged-guard.service' | 9 | export * from './unlogged-guard.service' |
10 | export * from './user-right-guard.service' | 10 | export * from './user-right-guard.service' |
11 | 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 3218040bf..76e28e461 100644 --- a/client/src/app/core/routing/redirect.service.ts +++ b/client/src/app/core/routing/redirect.service.ts | |||
@@ -7,11 +7,14 @@ export class RedirectService { | |||
7 | // Default route could change according to the instance configuration | 7 | // Default route could change according to the instance configuration |
8 | static INIT_DEFAULT_ROUTE = '/videos/trending' | 8 | static INIT_DEFAULT_ROUTE = '/videos/trending' |
9 | static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE | 9 | static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE |
10 | static INIT_DEFAULT_TRENDING_ROUTE = '/videos/most-viewed' | ||
11 | static DEFAULT_TRENDING_ROUTE = RedirectService.INIT_DEFAULT_TRENDING_ROUTE | ||
10 | 12 | ||
11 | private previousUrl: string | 13 | private previousUrl: string |
12 | private currentUrl: string | 14 | private currentUrl: string |
13 | 15 | ||
14 | private redirectingToHomepage = false | 16 | private redirectingToHomepage = false |
17 | private redirectingToTrending = false | ||
15 | 18 | ||
16 | constructor ( | 19 | constructor ( |
17 | private router: Router, | 20 | private router: Router, |
@@ -19,18 +22,28 @@ export class RedirectService { | |||
19 | ) { | 22 | ) { |
20 | // The config is first loaded from the cache so try to get the default route | 23 | // The config is first loaded from the cache so try to get the default route |
21 | const tmpConfig = this.serverService.getTmpConfig() | 24 | const tmpConfig = this.serverService.getTmpConfig() |
22 | if (tmpConfig && tmpConfig.instance && tmpConfig.instance.defaultClientRoute) { | 25 | if (tmpConfig && tmpConfig.instance) { |
23 | RedirectService.DEFAULT_ROUTE = tmpConfig.instance.defaultClientRoute | 26 | if (tmpConfig.instance.defaultClientRoute) { |
27 | RedirectService.DEFAULT_ROUTE = tmpConfig.instance.defaultClientRoute | ||
28 | } | ||
29 | if (tmpConfig.instance.defaultTrendingRoute) { | ||
30 | RedirectService.DEFAULT_TRENDING_ROUTE = tmpConfig.instance.defaultTrendingRoute | ||
31 | } | ||
24 | } | 32 | } |
25 | 33 | ||
26 | // Load default route | 34 | // Load default route |
27 | this.serverService.getConfig() | 35 | this.serverService.getConfig() |
28 | .subscribe(config => { | 36 | .subscribe(config => { |
29 | const defaultRouteConfig = config.instance.defaultClientRoute | 37 | const defaultRouteConfig = config.instance.defaultClientRoute |
38 | const defaultTrendingConfig = config.instance.defaultTrendingRoute | ||
30 | 39 | ||
31 | if (defaultRouteConfig) { | 40 | if (defaultRouteConfig) { |
32 | RedirectService.DEFAULT_ROUTE = defaultRouteConfig | 41 | RedirectService.DEFAULT_ROUTE = defaultRouteConfig |
33 | } | 42 | } |
43 | |||
44 | if (defaultTrendingConfig) { | ||
45 | RedirectService.DEFAULT_TRENDING_ROUTE = defaultTrendingConfig | ||
46 | } | ||
34 | }) | 47 | }) |
35 | 48 | ||
36 | // Track previous url | 49 | // Track previous url |
@@ -57,6 +70,15 @@ export class RedirectService { | |||
57 | return this.redirectToHomepage() | 70 | return this.redirectToHomepage() |
58 | } | 71 | } |
59 | 72 | ||
73 | redirectToTrending () { | ||
74 | if (this.redirectingToTrending) return | ||
75 | |||
76 | this.redirectingToTrending = true | ||
77 | |||
78 | this.router.navigate([ RedirectService.DEFAULT_TRENDING_ROUTE ]) | ||
79 | .then(() => this.redirectingToTrending = false) | ||
80 | } | ||
81 | |||
60 | redirectToHomepage (skipLocationChange = false) { | 82 | redirectToHomepage (skipLocationChange = false) { |
61 | if (this.redirectingToHomepage) return | 83 | if (this.redirectingToHomepage) return |
62 | 84 | ||
diff --git a/client/src/app/core/routing/trending-guard.service.ts b/client/src/app/core/routing/trending-guard.service.ts new file mode 100644 index 000000000..7db7fe994 --- /dev/null +++ b/client/src/app/core/routing/trending-guard.service.ts | |||
@@ -0,0 +1,14 @@ | |||
1 | import { Injectable } from '@angular/core' | ||
2 | import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router' | ||
3 | import { RedirectService } from './redirect.service' | ||
4 | |||
5 | @Injectable() | ||
6 | export class TrendingGuard implements CanActivate { | ||
7 | |||
8 | constructor (private redirectService: RedirectService) {} | ||
9 | |||
10 | canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { | ||
11 | this.redirectService.redirectToTrending() | ||
12 | return false | ||
13 | } | ||
14 | } | ||
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index b1d8fcf83..5f13190b4 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts | |||
@@ -36,9 +36,15 @@ export class ServerService { | |||
36 | name: 'PeerTube', | 36 | name: 'PeerTube', |
37 | shortDescription: 'PeerTube, a federated (ActivityPub) video streaming platform ' + | 37 | shortDescription: 'PeerTube, a federated (ActivityPub) video streaming platform ' + |
38 | 'using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.', | 38 | 'using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.', |
39 | defaultClientRoute: '', | ||
40 | isNSFW: false, | 39 | isNSFW: false, |
41 | defaultNSFWPolicy: 'do_not_list' as 'do_not_list', | 40 | defaultNSFWPolicy: 'do_not_list' as 'do_not_list', |
41 | defaultClientRoute: '', | ||
42 | defaultTrendingRoute: '', | ||
43 | pages: { | ||
44 | hot: { | ||
45 | enabled: true | ||
46 | } | ||
47 | }, | ||
42 | customizations: { | 48 | customizations: { |
43 | javascript: '', | 49 | javascript: '', |
44 | css: '' | 50 | css: '' |
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 9aa397edd..fc57b970b 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html | |||
@@ -127,10 +127,14 @@ | |||
127 | <ng-container i18n>Discover</ng-container> | 127 | <ng-container i18n>Discover</ng-container> |
128 | </a> | 128 | </a> |
129 | 129 | ||
130 | <a routerLink="/videos/trending" routerLinkActive="active"> | 130 | <a routerLink="/videos/trending" routerLinkActive="active" [ngClass]="{ 'active': hot.isActive || mostViewed.isActive || mostLiked.isActive }"> |
131 | <my-global-icon iconName="trending" aria-hidden="true"></my-global-icon> | 131 | <my-global-icon iconName="trending" aria-hidden="true"></my-global-icon> |
132 | <ng-container i18n>Trending</ng-container> | 132 | <ng-container i18n>Trending</ng-container> |
133 | </a> | 133 | </a> |
134 | <a routerLink="/videos/hot" routerLinkActive #hot="routerLinkActive" hidden></a> | ||
135 | <a routerLink="/videos/most-viewed" routerLinkActive #mostViewed="routerLinkActive" hidden></a> | ||
136 | <a routerLink="/videos/most-liked" routerLinkActive #mostLiked="routerLinkActive" hidden></a> | ||
137 | |||
134 | 138 | ||
135 | <a routerLink="/videos/recently-added" routerLinkActive="active"> | 139 | <a routerLink="/videos/recently-added" routerLinkActive="active"> |
136 | <my-global-icon iconName="recently-added" aria-hidden="true"></my-global-icon> | 140 | <my-global-icon iconName="recently-added" aria-hidden="true"></my-global-icon> |
diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.scss b/client/src/app/shared/shared-video-miniature/abstract-video-list.scss index 2eaf0dc70..0a8aa8fa4 100644 --- a/client/src/app/shared/shared-video-miniature/abstract-video-list.scss +++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.scss | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | $iconSize: 16px; | 6 | $iconSize: 16px; |
7 | 7 | ||
8 | ::ng-deep .title-page.title-page-single { | 8 | ::ng-deep my-video-list-header { |
9 | display: flex; | 9 | display: flex; |
10 | flex-grow: 1; | 10 | flex-grow: 1; |
11 | } | 11 | } |
diff --git a/client/src/app/shared/shared-video-miniature/video-list-header.component.html b/client/src/app/shared/shared-video-miniature/video-list-header.component.html new file mode 100644 index 000000000..58db437b8 --- /dev/null +++ b/client/src/app/shared/shared-video-miniature/video-list-header.component.html | |||
@@ -0,0 +1,5 @@ | |||
1 | <h1 class="title-page title-page-single"> | ||
2 | <div placement="bottom" [ngbTooltip]="data.titleTooltip" container="body"> | ||
3 | {{ data.titlePage }} | ||
4 | </div> | ||
5 | </h1> \ No newline at end of file | ||
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 a07248b96..67bbf7d7a 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,17 +1,13 @@ | |||
1 | import { Component, Inject } from '@angular/core' | 1 | import { Component, Inject, ViewEncapsulation } from '@angular/core' |
2 | 2 | ||
3 | export abstract class GenericHeaderComponent { | 3 | export abstract class GenericHeaderComponent { |
4 | constructor (@Inject('data') public data: any) {} | 4 | constructor (@Inject('data') public data: any) {} |
5 | } | 5 | } |
6 | 6 | ||
7 | @Component({ | 7 | @Component({ |
8 | selector: 'h1', | 8 | selector: 'my-video-list-header', |
9 | host: { 'class': 'title-page title-page-single' }, | 9 | encapsulation: ViewEncapsulation.None, |
10 | template: ` | 10 | templateUrl: './video-list-header.component.html' |
11 | <div placement="bottom" [ngbTooltip]="data.titleTooltip" container="body"> | ||
12 | {{ data.titlePage }} | ||
13 | </div> | ||
14 | ` | ||
15 | }) | 11 | }) |
16 | export class VideoListHeaderComponent extends GenericHeaderComponent { | 12 | export class VideoListHeaderComponent extends GenericHeaderComponent { |
17 | constructor (@Inject('data') public data: any) { | 13 | constructor (@Inject('data') public data: any) { |