aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+my-account/+my-account-video-channels/my-account-video-channels-routing.module.ts41
-rw-r--r--client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.module.ts31
-rw-r--r--client/src/app/+my-account/my-account-routing.module.ts97
-rw-r--r--client/src/app/+my-account/my-account.component.ts84
-rw-r--r--client/src/app/+my-account/my-account.module.ts37
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts)15
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.html)4
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.scss)0
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.ts)7
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts)12
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts41
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels.component.html (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.html)0
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.scss)0
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts (renamed from client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts)7
-rw-r--r--client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts31
-rw-r--r--client/src/app/+my-library/index.ts3
-rw-r--r--client/src/app/+my-library/my-history/my-history.component.html (renamed from client/src/app/+my-account/my-account-history/my-account-history.component.html)0
-rw-r--r--client/src/app/+my-library/my-history/my-history.component.scss (renamed from client/src/app/+my-account/my-account-history/my-account-history.component.scss)0
-rw-r--r--client/src/app/+my-library/my-history/my-history.component.ts (renamed from client/src/app/+my-account/my-account-history/my-account-history.component.ts)7
-rw-r--r--client/src/app/+my-library/my-library-routing.module.ts134
-rw-r--r--client/src/app/+my-library/my-library.component.html7
-rw-r--r--client/src/app/+my-library/my-library.component.scss13
-rw-r--r--client/src/app/+my-library/my-library.component.ts76
-rw-r--r--client/src/app/+my-library/my-library.module.ts79
-rw-r--r--client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.html (renamed from client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html)0
-rw-r--r--client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.scss (renamed from client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.scss)0
-rw-r--r--client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.ts (renamed from client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts)8
-rw-r--r--client/src/app/+my-library/my-ownership/my-ownership.component.html (renamed from client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html)2
-rw-r--r--client/src/app/+my-library/my-ownership/my-ownership.component.scss (renamed from client/src/app/+my-account/my-account-ownership/my-account-ownership.component.scss)0
-rw-r--r--client/src/app/+my-library/my-ownership/my-ownership.component.ts (renamed from client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts)16
-rw-r--r--client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html (renamed from client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html)0
-rw-r--r--client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss (renamed from client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.scss)0
-rw-r--r--client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts (renamed from client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts)9
-rw-r--r--client/src/app/+my-library/my-video-imports/my-video-imports.component.html (renamed from client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.html)0
-rw-r--r--client/src/app/+my-library/my-video-imports/my-video-imports.component.scss (renamed from client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.scss)0
-rw-r--r--client/src/app/+my-library/my-video-imports/my-video-imports.component.ts (renamed from client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts)9
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-create.component.ts (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts)11
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.html (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.html)4
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.scss (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.scss)0
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.ts (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.ts)2
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html)0
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss)0
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.ts (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts)11
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlist-update.component.ts (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts)11
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html)0
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss)0
-rw-r--r--client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts (renamed from client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts)7
-rw-r--r--client/src/app/+my-library/my-videos/modals/video-change-ownership.component.html (renamed from client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.html)0
-rw-r--r--client/src/app/+my-library/my-videos/modals/video-change-ownership.component.scss (renamed from client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.scss)0
-rw-r--r--client/src/app/+my-library/my-videos/modals/video-change-ownership.component.ts (renamed from client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.ts)0
-rw-r--r--client/src/app/+my-library/my-videos/my-videos.component.html (renamed from client/src/app/+my-account/my-account-videos/my-account-videos.component.html)12
-rw-r--r--client/src/app/+my-library/my-videos/my-videos.component.scss (renamed from client/src/app/+my-account/my-account-videos/my-account-videos.component.scss)63
-rw-r--r--client/src/app/+my-library/my-videos/my-videos.component.ts (renamed from client/src/app/+my-account/my-account-videos/my-account-videos.component.ts)7
-rw-r--r--client/src/app/+video-channels/video-channels.component.html2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts2
-rw-r--r--client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts2
-rw-r--r--client/src/app/+videos/video-list/video-user-subscriptions.component.ts2
-rw-r--r--client/src/app/app-routing.module.ts4
-rw-r--r--client/src/app/core/auth/auth.service.ts6
-rw-r--r--client/src/app/menu/menu.component.html179
-rw-r--r--client/src/app/menu/menu.component.scss296
-rw-r--r--client/src/app/menu/menu.component.ts42
-rw-r--r--client/src/app/shared/shared-main/users/user-notification.model.ts2
-rw-r--r--client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html2
-rw-r--r--client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.ts2
65 files changed, 842 insertions, 597 deletions
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels-routing.module.ts b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels-routing.module.ts
deleted file mode 100644
index 3aa3e360f..000000000
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels-routing.module.ts
+++ /dev/null
@@ -1,41 +0,0 @@
1import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router'
3import { MyAccountVideoChannelUpdateComponent } from './my-account-video-channel-update.component'
4import { MyAccountVideoChannelCreateComponent } from './my-account-video-channel-create.component'
5import { MyAccountVideoChannelsComponent } from './my-account-video-channels.component'
6
7const myAccountVideoChannelsRoutes: Routes = [
8 {
9 path: '',
10 component: MyAccountVideoChannelsComponent,
11 data: {
12 meta: {
13 title: $localize`Account video channels`
14 }
15 }
16 },
17 {
18 path: 'create',
19 component: MyAccountVideoChannelCreateComponent,
20 data: {
21 meta: {
22 title: $localize`Create new video channel`
23 }
24 }
25 },
26 {
27 path: 'update/:videoChannelId',
28 component: MyAccountVideoChannelUpdateComponent,
29 data: {
30 meta: {
31 title: $localize`Update video channel`
32 }
33 }
34 }
35]
36
37@NgModule({
38 imports: [ RouterModule.forChild(myAccountVideoChannelsRoutes) ],
39 exports: [ RouterModule ]
40})
41export class MyAccountVideoChannelsRoutingModule {}
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.module.ts b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.module.ts
deleted file mode 100644
index f8c6ad56b..000000000
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.module.ts
+++ /dev/null
@@ -1,31 +0,0 @@
1import { ChartModule } from 'primeng/chart'
2import { NgModule } from '@angular/core'
3import { SharedFormModule } from '@app/shared/shared-forms'
4import { SharedGlobalIconModule } from '@app/shared/shared-icons'
5import { SharedMainModule } from '@app/shared/shared-main'
6import { MyAccountVideoChannelCreateComponent } from './my-account-video-channel-create.component'
7import { MyAccountVideoChannelUpdateComponent } from './my-account-video-channel-update.component'
8import { MyAccountVideoChannelsRoutingModule } from './my-account-video-channels-routing.module'
9import { MyAccountVideoChannelsComponent } from './my-account-video-channels.component'
10
11@NgModule({
12 imports: [
13 MyAccountVideoChannelsRoutingModule,
14
15 ChartModule,
16
17 SharedMainModule,
18 SharedFormModule,
19 SharedGlobalIconModule
20 ],
21
22 declarations: [
23 MyAccountVideoChannelsComponent,
24 MyAccountVideoChannelCreateComponent,
25 MyAccountVideoChannelUpdateComponent
26 ],
27
28 exports: [],
29 providers: []
30})
31export class MyAccountVideoChannelsModule { }
diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts
index 0bcb38ef5..81380ec6e 100644
--- a/client/src/app/+my-account/my-account-routing.module.ts
+++ b/client/src/app/+my-account/my-account-routing.module.ts
@@ -2,21 +2,12 @@ import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router' 2import { RouterModule, Routes } from '@angular/router'
3import { MetaGuard } from '@ngx-meta/core' 3import { MetaGuard } from '@ngx-meta/core'
4import { LoginGuard } from '../core' 4import { LoginGuard } from '../core'
5import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component'
5import { MyAccountBlocklistComponent } from './my-account-blocklist/my-account-blocklist.component' 6import { MyAccountBlocklistComponent } from './my-account-blocklist/my-account-blocklist.component'
6import { MyAccountServerBlocklistComponent } from './my-account-blocklist/my-account-server-blocklist.component' 7import { MyAccountServerBlocklistComponent } from './my-account-blocklist/my-account-server-blocklist.component'
7import { MyAccountHistoryComponent } from './my-account-history/my-account-history.component'
8import { MyAccountNotificationsComponent } from './my-account-notifications/my-account-notifications.component' 8import { MyAccountNotificationsComponent } from './my-account-notifications/my-account-notifications.component'
9import { MyAccountOwnershipComponent } from './my-account-ownership/my-account-ownership.component'
10import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' 9import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component'
11import { MyAccountSubscriptionsComponent } from './my-account-subscriptions/my-account-subscriptions.component'
12import { MyAccountVideoImportsComponent } from './my-account-video-imports/my-account-video-imports.component'
13import { MyAccountVideoPlaylistCreateComponent } from './my-account-video-playlists/my-account-video-playlist-create.component'
14import { MyAccountVideoPlaylistElementsComponent } from './my-account-video-playlists/my-account-video-playlist-elements.component'
15import { MyAccountVideoPlaylistUpdateComponent } from './my-account-video-playlists/my-account-video-playlist-update.component'
16import { MyAccountVideoPlaylistsComponent } from './my-account-video-playlists/my-account-video-playlists.component'
17import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component'
18import { MyAccountComponent } from './my-account.component' 10import { MyAccountComponent } from './my-account.component'
19import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component'
20 11
21const myAccountRoutes: Routes = [ 12const myAccountRoutes: Routes = [
22 { 13 {
@@ -41,88 +32,50 @@ const myAccountRoutes: Routes = [
41 32
42 { 33 {
43 path: 'video-channels', 34 path: 'video-channels',
44 loadChildren: () => { 35 redirectTo: '/my-library/video-channels',
45 return import('./+my-account-video-channels/my-account-video-channels.module') 36 pathMatch: 'full'
46 .then(m => m.MyAccountVideoChannelsModule)
47 }
48 }, 37 },
49 38
50 { 39 {
51 path: 'video-playlists', 40 path: 'video-playlists',
52 component: MyAccountVideoPlaylistsComponent, 41 redirectTo: '/my-library/video-playlists',
53 data: { 42 pathMatch: 'full'
54 meta: {
55 title: $localize`Account playlists`
56 }
57 }
58 }, 43 },
59 { 44 {
60 path: 'video-playlists/create', 45 path: 'video-playlists/create',
61 component: MyAccountVideoPlaylistCreateComponent, 46 redirectTo: '/my-library/video-playlists/create',
62 data: { 47 pathMatch: 'full'
63 meta: {
64 title: $localize`Create new playlist`
65 }
66 }
67 }, 48 },
68 { 49 {
69 path: 'video-playlists/:videoPlaylistId', 50 path: 'video-playlists/:videoPlaylistId',
70 component: MyAccountVideoPlaylistElementsComponent, 51 redirectTo: '/my-library/video-playlists/:videoPlaylistId',
71 data: { 52 pathMatch: 'full'
72 meta: {
73 title: $localize`Playlist elements`
74 }
75 }
76 }, 53 },
77 { 54 {
78 path: 'video-playlists/update/:videoPlaylistId', 55 path: 'video-playlists/update/:videoPlaylistId',
79 component: MyAccountVideoPlaylistUpdateComponent, 56 redirectTo: '/my-library/video-playlists/update/:videoPlaylistId',
80 data: { 57 pathMatch: 'full'
81 meta: {
82 title: $localize`Update playlist`
83 }
84 }
85 }, 58 },
86 59
87 { 60 {
88 path: 'videos', 61 path: 'videos',
89 component: MyAccountVideosComponent, 62 redirectTo: '/my-library/videos',
90 data: { 63 pathMatch: 'full'
91 meta: {
92 title: $localize`Account videos`
93 },
94 reuse: {
95 enabled: true,
96 key: 'my-account-videos-list'
97 }
98 }
99 }, 64 },
100 { 65 {
101 path: 'video-imports', 66 path: 'video-imports',
102 component: MyAccountVideoImportsComponent, 67 redirectTo: '/my-library/video-imports',
103 data: { 68 pathMatch: 'full'
104 meta: {
105 title: $localize`Account video imports`
106 }
107 }
108 }, 69 },
109 { 70 {
110 path: 'subscriptions', 71 path: 'subscriptions',
111 component: MyAccountSubscriptionsComponent, 72 redirectTo: '/my-library/subscriptions',
112 data: { 73 pathMatch: 'full'
113 meta: {
114 title: $localize`Account subscriptions`
115 }
116 }
117 }, 74 },
118 { 75 {
119 path: 'ownership', 76 path: 'ownership',
120 component: MyAccountOwnershipComponent, 77 redirectTo: '/my-library/ownership',
121 data: { 78 pathMatch: 'full'
122 meta: {
123 title: $localize`Ownership changes`
124 }
125 }
126 }, 79 },
127 { 80 {
128 path: 'blocklist/accounts', 81 path: 'blocklist/accounts',
@@ -144,16 +97,8 @@ const myAccountRoutes: Routes = [
144 }, 97 },
145 { 98 {
146 path: 'history/videos', 99 path: 'history/videos',
147 component: MyAccountHistoryComponent, 100 redirectTo: '/my-library/history/videos',
148 data: { 101 pathMatch: 'full'
149 meta: {
150 title: $localize`Videos history`
151 },
152 reuse: {
153 enabled: true,
154 key: 'my-videos-history-list'
155 }
156 }
157 }, 102 },
158 { 103 {
159 path: 'notifications', 104 path: 'notifications',
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts
index d3bf8d143..d6e9d1c15 100644
--- a/client/src/app/+my-account/my-account.component.ts
+++ b/client/src/app/+my-account/my-account.component.ts
@@ -1,6 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { AuthService, AuthUser, ScreenService, ServerService } from '@app/core' 2import { AuthUser, ScreenService } from '@app/core'
3import { ServerConfig } from '@shared/models'
4import { TopMenuDropdownParam } from '../shared/shared-main/misc/top-menu-dropdown.component' 3import { TopMenuDropdownParam } from '../shared/shared-main/misc/top-menu-dropdown.component'
5 4
6@Component({ 5@Component({
@@ -12,11 +11,7 @@ export class MyAccountComponent implements OnInit {
12 menuEntries: TopMenuDropdownParam[] = [] 11 menuEntries: TopMenuDropdownParam[] = []
13 user: AuthUser 12 user: AuthUser
14 13
15 private serverConfig: ServerConfig
16
17 constructor ( 14 constructor (
18 private serverService: ServerService,
19 private authService: AuthService,
20 private screenService: ScreenService 15 private screenService: ScreenService
21 ) { } 16 ) { }
22 17
@@ -25,67 +20,12 @@ export class MyAccountComponent implements OnInit {
25 } 20 }
26 21
27 ngOnInit (): void { 22 ngOnInit (): void {
28 this.serverConfig = this.serverService.getTmpConfig() 23 this.buildMenu()
29 this.serverService.getConfig()
30 .subscribe(config => this.serverConfig = config)
31
32 this.user = this.authService.getUser()
33
34 this.authService.userInformationLoaded.subscribe(
35 () => this.buildMenu()
36 )
37 }
38
39 isVideoImportEnabled () {
40 const importConfig = this.serverConfig.import.videos
41
42 return importConfig.http.enabled || importConfig.torrent.enabled
43 } 24 }
44 25
45 private buildMenu () { 26 private buildMenu () {
46 const libraryEntries: TopMenuDropdownParam = { 27 const moderationEntries: TopMenuDropdownParam = {
47 label: $localize`My library`, 28 label: $localize`Moderation`,
48 children: [
49 {
50 label: $localize`My channels`,
51 routerLink: '/my-account/video-channels',
52 iconName: 'channel'
53 },
54 {
55 label: $localize`My videos`,
56 routerLink: '/my-account/videos',
57 iconName: 'videos',
58 isDisplayed: () => this.user.canSeeVideosLink
59 },
60 {
61 label: $localize`My playlists`,
62 routerLink: '/my-account/video-playlists',
63 iconName: 'playlists'
64 },
65 {
66 label: $localize`My subscriptions`,
67 routerLink: '/my-account/subscriptions',
68 iconName: 'subscriptions'
69 },
70 {
71 label: $localize`My history`,
72 routerLink: '/my-account/history/videos',
73 iconName: 'history'
74 }
75 ]
76 }
77
78 if (this.isVideoImportEnabled()) {
79 libraryEntries.children.push({
80 label: 'My imports',
81 routerLink: '/my-account/video-imports',
82 iconName: 'cloud-download',
83 isDisplayed: () => this.user.canSeeVideosLink
84 })
85 }
86
87 const miscEntries: TopMenuDropdownParam = {
88 label: $localize`Misc`,
89 children: [ 29 children: [
90 { 30 {
91 label: $localize`Muted accounts`, 31 label: $localize`Muted accounts`,
@@ -98,29 +38,25 @@ export class MyAccountComponent implements OnInit {
98 iconName: 'peertube-x' 38 iconName: 'peertube-x'
99 }, 39 },
100 { 40 {
101 label: $localize`My abuse reports`, 41 label: $localize`Abuse reports`,
102 routerLink: '/my-account/abuses', 42 routerLink: '/my-account/abuses',
103 iconName: 'flag' 43 iconName: 'flag'
104 },
105 {
106 label: $localize`Ownership changes`,
107 routerLink: '/my-account/ownership',
108 iconName: 'download'
109 } 44 }
110 ] 45 ]
111 } 46 }
112 47
113 this.menuEntries = [ 48 this.menuEntries = [
114 { 49 {
115 label: $localize`My settings`, 50 label: $localize`Settings`,
116 routerLink: '/my-account/settings' 51 routerLink: '/my-account/settings'
117 }, 52 },
53
118 { 54 {
119 label: $localize`My notifications`, 55 label: $localize`Notifications`,
120 routerLink: '/my-account/notifications' 56 routerLink: '/my-account/notifications'
121 }, 57 },
122 libraryEntries, 58
123 miscEntries 59 moderationEntries
124 ] 60 ]
125 } 61 }
126} 62}
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts
index 6d21fff72..d3b6a9fa3 100644
--- a/client/src/app/+my-account/my-account.module.ts
+++ b/client/src/app/+my-account/my-account.module.ts
@@ -6,21 +6,14 @@ import { NgModule } from '@angular/core'
6import { SharedAbuseListModule } from '@app/shared/shared-abuse-list' 6import { SharedAbuseListModule } from '@app/shared/shared-abuse-list'
7import { SharedFormModule } from '@app/shared/shared-forms' 7import { SharedFormModule } from '@app/shared/shared-forms'
8import { SharedGlobalIconModule } from '@app/shared/shared-icons' 8import { SharedGlobalIconModule } from '@app/shared/shared-icons'
9import { SharedVideoLiveModule } from '@app/shared/shared-video-live'
10import { SharedMainModule } from '@app/shared/shared-main' 9import { SharedMainModule } from '@app/shared/shared-main'
11import { SharedModerationModule } from '@app/shared/shared-moderation' 10import { SharedModerationModule } from '@app/shared/shared-moderation'
12import { SharedShareModal } from '@app/shared/shared-share-modal' 11import { SharedShareModal } from '@app/shared/shared-share-modal'
13import { SharedUserInterfaceSettingsModule } from '@app/shared/shared-user-settings' 12import { SharedUserInterfaceSettingsModule } from '@app/shared/shared-user-settings'
14import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription/shared-user-subscription.module'
15import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
16import { SharedVideoPlaylistModule } from '@app/shared/shared-video-playlist/shared-video-playlist.module'
17import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component' 13import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component'
18import { MyAccountBlocklistComponent } from './my-account-blocklist/my-account-blocklist.component' 14import { MyAccountBlocklistComponent } from './my-account-blocklist/my-account-blocklist.component'
19import { MyAccountServerBlocklistComponent } from './my-account-blocklist/my-account-server-blocklist.component' 15import { MyAccountServerBlocklistComponent } from './my-account-blocklist/my-account-server-blocklist.component'
20import { MyAccountHistoryComponent } from './my-account-history/my-account-history.component'
21import { MyAccountNotificationsComponent } from './my-account-notifications/my-account-notifications.component' 16import { MyAccountNotificationsComponent } from './my-account-notifications/my-account-notifications.component'
22import { MyAccountAcceptOwnershipComponent } from './my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component'
23import { MyAccountOwnershipComponent } from './my-account-ownership/my-account-ownership.component'
24import { MyAccountRoutingModule } from './my-account-routing.module' 17import { MyAccountRoutingModule } from './my-account-routing.module'
25import { MyAccountChangeEmailComponent } from './my-account-settings/my-account-change-email' 18import { MyAccountChangeEmailComponent } from './my-account-settings/my-account-change-email'
26import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component' 19import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component'
@@ -28,14 +21,6 @@ import { MyAccountDangerZoneComponent } from './my-account-settings/my-account-d
28import { MyAccountNotificationPreferencesComponent } from './my-account-settings/my-account-notification-preferences' 21import { MyAccountNotificationPreferencesComponent } from './my-account-settings/my-account-notification-preferences'
29import { MyAccountProfileComponent } from './my-account-settings/my-account-profile/my-account-profile.component' 22import { MyAccountProfileComponent } from './my-account-settings/my-account-profile/my-account-profile.component'
30import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' 23import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component'
31import { MyAccountSubscriptionsComponent } from './my-account-subscriptions/my-account-subscriptions.component'
32import { MyAccountVideoImportsComponent } from './my-account-video-imports/my-account-video-imports.component'
33import { MyAccountVideoPlaylistCreateComponent } from './my-account-video-playlists/my-account-video-playlist-create.component'
34import { MyAccountVideoPlaylistElementsComponent } from './my-account-video-playlists/my-account-video-playlist-elements.component'
35import { MyAccountVideoPlaylistUpdateComponent } from './my-account-video-playlists/my-account-video-playlist-update.component'
36import { MyAccountVideoPlaylistsComponent } from './my-account-video-playlists/my-account-video-playlists.component'
37import { VideoChangeOwnershipComponent } from './my-account-videos/modals/video-change-ownership.component'
38import { MyAccountVideosComponent } from './my-account-videos/my-account-videos.component'
39import { MyAccountComponent } from './my-account.component' 24import { MyAccountComponent } from './my-account.component'
40 25
41@NgModule({ 26@NgModule({
@@ -50,14 +35,10 @@ import { MyAccountComponent } from './my-account.component'
50 SharedMainModule, 35 SharedMainModule,
51 SharedFormModule, 36 SharedFormModule,
52 SharedModerationModule, 37 SharedModerationModule,
53 SharedVideoMiniatureModule,
54 SharedUserSubscriptionModule,
55 SharedVideoPlaylistModule,
56 SharedUserInterfaceSettingsModule, 38 SharedUserInterfaceSettingsModule,
57 SharedGlobalIconModule, 39 SharedGlobalIconModule,
58 SharedAbuseListModule, 40 SharedAbuseListModule,
59 SharedShareModal, 41 SharedShareModal
60 SharedVideoLiveModule
61 ], 42 ],
62 43
63 declarations: [ 44 declarations: [
@@ -67,26 +48,12 @@ import { MyAccountComponent } from './my-account.component'
67 MyAccountProfileComponent, 48 MyAccountProfileComponent,
68 MyAccountChangeEmailComponent, 49 MyAccountChangeEmailComponent,
69 50
70 MyAccountVideosComponent,
71
72 VideoChangeOwnershipComponent,
73
74 MyAccountOwnershipComponent,
75 MyAccountAcceptOwnershipComponent,
76 MyAccountVideoImportsComponent,
77 MyAccountDangerZoneComponent, 51 MyAccountDangerZoneComponent,
78 MyAccountSubscriptionsComponent,
79 MyAccountBlocklistComponent, 52 MyAccountBlocklistComponent,
80 MyAccountAbusesListComponent, 53 MyAccountAbusesListComponent,
81 MyAccountServerBlocklistComponent, 54 MyAccountServerBlocklistComponent,
82 MyAccountHistoryComponent,
83 MyAccountNotificationsComponent, 55 MyAccountNotificationsComponent,
84 MyAccountNotificationPreferencesComponent, 56 MyAccountNotificationPreferencesComponent
85
86 MyAccountVideoPlaylistCreateComponent,
87 MyAccountVideoPlaylistUpdateComponent,
88 MyAccountVideoPlaylistsComponent,
89 MyAccountVideoPlaylistElementsComponent
90 ], 57 ],
91 58
92 exports: [ 59 exports: [
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts
index e2ea87fb8..1d0cbf246 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts
@@ -10,14 +10,13 @@ import {
10import { FormValidatorService } from '@app/shared/shared-forms' 10import { FormValidatorService } from '@app/shared/shared-forms'
11import { VideoChannelService } from '@app/shared/shared-main' 11import { VideoChannelService } from '@app/shared/shared-main'
12import { VideoChannelCreate } from '@shared/models' 12import { VideoChannelCreate } from '@shared/models'
13import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 13import { MyVideoChannelEdit } from './my-video-channel-edit'
14 14
15@Component({ 15@Component({
16 selector: 'my-account-video-channel-create', 16 templateUrl: './my-video-channel-edit.component.html',
17 templateUrl: './my-account-video-channel-edit.component.html', 17 styleUrls: [ './my-video-channel-edit.component.scss' ]
18 styleUrls: [ './my-account-video-channel-edit.component.scss' ]
19}) 18})
20export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelEdit implements OnInit { 19export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit {
21 error: string 20 error: string
22 21
23 constructor ( 22 constructor (
@@ -30,10 +29,6 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
30 super() 29 super()
31 } 30 }
32 31
33 get instanceHost () {
34 return window.location.host
35 }
36
37 ngOnInit () { 32 ngOnInit () {
38 this.buildForm({ 33 this.buildForm({
39 name: VIDEO_CHANNEL_NAME_VALIDATOR, 34 name: VIDEO_CHANNEL_NAME_VALIDATOR,
@@ -59,7 +54,7 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
59 this.authService.refreshUserInformation() 54 this.authService.refreshUserInformation()
60 55
61 this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) 56 this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`)
62 this.router.navigate([ '/my-account', 'video-channels' ]) 57 this.router.navigate([ '/my-library', 'video-channels' ])
63 }, 58 },
64 59
65 err => { 60 err => {
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html
index 048d143cd..7e0c4e732 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.html
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html
@@ -1,7 +1,7 @@
1<nav aria-label="breadcrumb"> 1<nav aria-label="breadcrumb">
2 <ol class="breadcrumb"> 2 <ol class="breadcrumb">
3 <li class="breadcrumb-item"> 3 <li class="breadcrumb-item">
4 <a routerLink="/my-account/video-channels" i18n>My Channels</a> 4 <a routerLink="/my-library/video-channels" i18n>My Channels</a>
5 </li> 5 </li>
6 6
7 <ng-container *ngIf="isCreation()"> 7 <ng-container *ngIf="isCreation()">
@@ -10,7 +10,7 @@
10 <ng-container *ngIf="!isCreation()"> 10 <ng-container *ngIf="!isCreation()">
11 <li class="breadcrumb-item active" i18n>Edit</li> 11 <li class="breadcrumb-item active" i18n>Edit</li>
12 <li class="breadcrumb-item active" aria-current="page"> 12 <li class="breadcrumb-item active" aria-current="page">
13 <a *ngIf="videoChannelToUpdate" [routerLink]="[ '/my-account/video-channels/update', videoChannelToUpdate?.nameWithHost ]">{{ videoChannelToUpdate?.displayName }}</a> 13 <a *ngIf="videoChannelToUpdate" [routerLink]="[ '/my-library/video-channels/update', videoChannelToUpdate?.nameWithHost ]">{{ videoChannelToUpdate?.displayName }}</a>
14 </li> 14 </li>
15 </ng-container> 15 </ng-container>
16 </ol> 16 </ol>
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss
index 8f8af655c..8f8af655c 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.component.scss
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts
index 710c51d8e..09db0df9d 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-edit.ts
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts
@@ -1,14 +1,17 @@
1import { FormReactive } from '@app/shared/shared-forms' 1import { FormReactive } from '@app/shared/shared-forms'
2import { VideoChannel } from '@app/shared/shared-main' 2import { VideoChannel } from '@app/shared/shared-main'
3 3
4export abstract class MyAccountVideoChannelEdit extends FormReactive { 4export abstract class MyVideoChannelEdit extends FormReactive {
5 // We need it even in the create component because it's used in the edit template 5 // We need it even in the create component because it's used in the edit template
6 videoChannelToUpdate: VideoChannel 6 videoChannelToUpdate: VideoChannel
7 instanceHost: string
8 7
9 abstract isCreation (): boolean 8 abstract isCreation (): boolean
10 abstract getFormButtonTitle (): string 9 abstract getFormButtonTitle (): string
11 10
11 get instanceHost () {
12 return window.location.host
13 }
14
12 // We need this method so angular does not complain in child template that doesn't need this 15 // We need this method so angular does not complain in child template that doesn't need this
13 onAvatarChange (formData: FormData) { /* empty */ } 16 onAvatarChange (formData: FormData) { /* empty */ }
14 17
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts
index 01659b8da..c6cb5ade6 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts
@@ -10,14 +10,14 @@ import {
10import { FormValidatorService } from '@app/shared/shared-forms' 10import { FormValidatorService } from '@app/shared/shared-forms'
11import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' 11import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
12import { ServerConfig, VideoChannelUpdate } from '@shared/models' 12import { ServerConfig, VideoChannelUpdate } from '@shared/models'
13import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 13import { MyVideoChannelEdit } from './my-video-channel-edit'
14 14
15@Component({ 15@Component({
16 selector: 'my-account-video-channel-update', 16 selector: 'my-video-channel-update',
17 templateUrl: './my-account-video-channel-edit.component.html', 17 templateUrl: './my-video-channel-edit.component.html',
18 styleUrls: [ './my-account-video-channel-edit.component.scss' ] 18 styleUrls: [ './my-video-channel-edit.component.scss' ]
19}) 19})
20export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy { 20export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy {
21 error: string 21 error: string
22 videoChannelToUpdate: VideoChannel 22 videoChannelToUpdate: VideoChannel
23 23
@@ -91,7 +91,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
91 91
92 this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`) 92 this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`)
93 93
94 this.router.navigate([ '/my-account', 'video-channels' ]) 94 this.router.navigate([ '/my-library', 'video-channels' ])
95 }, 95 },
96 96
97 err => this.error = err.message 97 err => this.error = err.message
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts
new file mode 100644
index 000000000..6b8efad0b
--- /dev/null
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels-routing.module.ts
@@ -0,0 +1,41 @@
1import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router'
3import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component'
4import { MyVideoChannelCreateComponent } from './my-video-channel-create.component'
5import { MyVideoChannelsComponent } from './my-video-channels.component'
6
7const myVideoChannelsRoutes: Routes = [
8 {
9 path: '',
10 component: MyVideoChannelsComponent,
11 data: {
12 meta: {
13 title: $localize`My video channels`
14 }
15 }
16 },
17 {
18 path: 'create',
19 component: MyVideoChannelCreateComponent,
20 data: {
21 meta: {
22 title: $localize`Create a new video channel`
23 }
24 }
25 },
26 {
27 path: 'update/:videoChannelId',
28 component: MyVideoChannelUpdateComponent,
29 data: {
30 meta: {
31 title: $localize`Update video channel`
32 }
33 }
34 }
35]
36
37@NgModule({
38 imports: [ RouterModule.forChild(myVideoChannelsRoutes) ],
39 exports: [ RouterModule ]
40})
41export class MyVideoChannelsRoutingModule {}
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
index 205d23cd5..205d23cd5 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.html
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.html
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.scss b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss
index f2f42459f..f2f42459f 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.scss
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.scss
diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts
index 281801ff6..a63e98a51 100644
--- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.component.ts
@@ -7,11 +7,10 @@ import { AuthService, ConfirmService, Notifier, ScreenService, User } from '@app
7import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' 7import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
8 8
9@Component({ 9@Component({
10 selector: 'my-account-video-channels', 10 templateUrl: './my-video-channels.component.html',
11 templateUrl: './my-account-video-channels.component.html', 11 styleUrls: [ './my-video-channels.component.scss' ]
12 styleUrls: [ './my-account-video-channels.component.scss' ]
13}) 12})
14export class MyAccountVideoChannelsComponent implements OnInit { 13export class MyVideoChannelsComponent implements OnInit {
15 totalItems: number 14 totalItems: number
16 15
17 videoChannels: VideoChannel[] = [] 16 videoChannels: VideoChannel[] = []
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts
new file mode 100644
index 000000000..92b56db49
--- /dev/null
+++ b/client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts
@@ -0,0 +1,31 @@
1import { ChartModule } from 'primeng/chart'
2import { NgModule } from '@angular/core'
3import { SharedFormModule } from '@app/shared/shared-forms'
4import { SharedGlobalIconModule } from '@app/shared/shared-icons'
5import { SharedMainModule } from '@app/shared/shared-main'
6import { MyVideoChannelCreateComponent } from './my-video-channel-create.component'
7import { MyVideoChannelUpdateComponent } from './my-video-channel-update.component'
8import { MyVideoChannelsRoutingModule } from './my-video-channels-routing.module'
9import { MyVideoChannelsComponent } from './my-video-channels.component'
10
11@NgModule({
12 imports: [
13 MyVideoChannelsRoutingModule,
14
15 ChartModule,
16
17 SharedMainModule,
18 SharedFormModule,
19 SharedGlobalIconModule
20 ],
21
22 declarations: [
23 MyVideoChannelsComponent,
24 MyVideoChannelCreateComponent,
25 MyVideoChannelUpdateComponent
26 ],
27
28 exports: [],
29 providers: []
30})
31export class MyVideoChannelsModule { }
diff --git a/client/src/app/+my-library/index.ts b/client/src/app/+my-library/index.ts
new file mode 100644
index 000000000..d51a36a7c
--- /dev/null
+++ b/client/src/app/+my-library/index.ts
@@ -0,0 +1,3 @@
1export * from './my-library-routing.module'
2export * from './my-library.component'
3export * from './my-library.module'
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-library/my-history/my-history.component.html
index cff46a41d..cff46a41d 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.html
+++ b/client/src/app/+my-library/my-history/my-history.component.html
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.scss b/client/src/app/+my-library/my-history/my-history.component.scss
index 9eeeaf310..9eeeaf310 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.scss
+++ b/client/src/app/+my-library/my-history/my-history.component.scss
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.ts b/client/src/app/+my-library/my-history/my-history.component.ts
index 3298c56c7..e11f05c47 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.ts
+++ b/client/src/app/+my-library/my-history/my-history.component.ts
@@ -15,11 +15,10 @@ import { UserHistoryService } from '@app/shared/shared-main'
15import { AbstractVideoList } from '@app/shared/shared-video-miniature' 15import { AbstractVideoList } from '@app/shared/shared-video-miniature'
16 16
17@Component({ 17@Component({
18 selector: 'my-account-history', 18 templateUrl: './my-history.component.html',
19 templateUrl: './my-account-history.component.html', 19 styleUrls: [ './my-history.component.scss' ]
20 styleUrls: [ './my-account-history.component.scss' ]
21}) 20})
22export class MyAccountHistoryComponent extends AbstractVideoList implements OnInit, OnDestroy { 21export class MyHistoryComponent extends AbstractVideoList implements OnInit, OnDestroy {
23 titlePage: string 22 titlePage: string
24 pagination: ComponentPagination = { 23 pagination: ComponentPagination = {
25 currentPage: 1, 24 currentPage: 1,
diff --git a/client/src/app/+my-library/my-library-routing.module.ts b/client/src/app/+my-library/my-library-routing.module.ts
new file mode 100644
index 000000000..d8e5aa562
--- /dev/null
+++ b/client/src/app/+my-library/my-library-routing.module.ts
@@ -0,0 +1,134 @@
1import { NgModule } from '@angular/core'
2import { RouterModule, Routes } from '@angular/router'
3import { MetaGuard } from '@ngx-meta/core'
4import { LoginGuard } from '../core'
5import { MyHistoryComponent } from './my-history/my-history.component'
6import { MyLibraryComponent } from './my-library.component'
7import { MyOwnershipComponent } from './my-ownership/my-ownership.component'
8import { MySubscriptionsComponent } from './my-subscriptions/my-subscriptions.component'
9import { MyVideoImportsComponent } from './my-video-imports/my-video-imports.component'
10import { MyVideoPlaylistCreateComponent } from './my-video-playlists/my-video-playlist-create.component'
11import { MyVideoPlaylistElementsComponent } from './my-video-playlists/my-video-playlist-elements.component'
12import { MyVideoPlaylistUpdateComponent } from './my-video-playlists/my-video-playlist-update.component'
13import { MyVideoPlaylistsComponent } from './my-video-playlists/my-video-playlists.component'
14import { MyVideosComponent } from './my-videos/my-videos.component'
15
16const myLibraryRoutes: Routes = [
17 {
18 path: '',
19 component: MyLibraryComponent,
20 canActivateChild: [ MetaGuard, LoginGuard ],
21 children: [
22 {
23 path: '',
24 redirectTo: 'video-channels',
25 pathMatch: 'full'
26 },
27
28 {
29 path: 'video-channels',
30 loadChildren: () => {
31 return import('./+my-video-channels/my-video-channels.module').then(m => m.MyVideoChannelsModule)
32 }
33 },
34
35 {
36 path: 'video-playlists',
37 component: MyVideoPlaylistsComponent,
38 data: {
39 meta: {
40 title: $localize`My playlists`
41 }
42 }
43 },
44 {
45 path: 'video-playlists/create',
46 component: MyVideoPlaylistCreateComponent,
47 data: {
48 meta: {
49 title: $localize`Create a new playlist`
50 }
51 }
52 },
53 {
54 path: 'video-playlists/:videoPlaylistId',
55 component: MyVideoPlaylistElementsComponent,
56 data: {
57 meta: {
58 title: $localize`Playlist elements`
59 }
60 }
61 },
62 {
63 path: 'video-playlists/update/:videoPlaylistId',
64 component: MyVideoPlaylistUpdateComponent,
65 data: {
66 meta: {
67 title: $localize`Update playlist`
68 }
69 }
70 },
71
72 {
73 path: 'videos',
74 component: MyVideosComponent,
75 data: {
76 meta: {
77 title: $localize`My videos`
78 },
79 reuse: {
80 enabled: true,
81 key: 'my-videos-list'
82 }
83 }
84 },
85 {
86 path: 'video-imports',
87 component: MyVideoImportsComponent,
88 data: {
89 meta: {
90 title: $localize`My video imports`
91 }
92 }
93 },
94 {
95 path: 'subscriptions',
96 component: MySubscriptionsComponent,
97 data: {
98 meta: {
99 title: $localize`My subscriptions`
100 }
101 }
102 },
103 {
104 path: 'ownership',
105 component: MyOwnershipComponent,
106 data: {
107 meta: {
108 title: $localize`Ownership changes`
109 }
110 }
111 },
112
113 {
114 path: 'history/videos',
115 component: MyHistoryComponent,
116 data: {
117 meta: {
118 title: $localize`My video history`
119 },
120 reuse: {
121 enabled: true,
122 key: 'my-videos-history-list'
123 }
124 }
125 }
126 ]
127 }
128]
129
130@NgModule({
131 imports: [ RouterModule.forChild(myLibraryRoutes) ],
132 exports: [ RouterModule ]
133})
134export class MyLibraryRoutingModule {}
diff --git a/client/src/app/+my-library/my-library.component.html b/client/src/app/+my-library/my-library.component.html
new file mode 100644
index 000000000..b465d0156
--- /dev/null
+++ b/client/src/app/+my-library/my-library.component.html
@@ -0,0 +1,7 @@
1<div class="row">
2 <my-top-menu-dropdown [menuEntries]="menuEntries"></my-top-menu-dropdown>
3
4 <div class="margin-content pb-5" [ngClass]="{ 'offset-content': !isBroadcastMessageDisplayed }">
5 <router-outlet></router-outlet>
6 </div>
7</div>
diff --git a/client/src/app/+my-library/my-library.component.scss b/client/src/app/+my-library/my-library.component.scss
new file mode 100644
index 000000000..a5bb499b4
--- /dev/null
+++ b/client/src/app/+my-library/my-library.component.scss
@@ -0,0 +1,13 @@
1@import '_variables';
2@import '_mixins';
3
4.row {
5 flex-direction: column;
6 width: 100%;
7
8 & > my-top-menu-dropdown:nth-child(1) {
9 flex-grow: 1;
10 }
11
12 @include sub-menu-h1;
13}
diff --git a/client/src/app/+my-library/my-library.component.ts b/client/src/app/+my-library/my-library.component.ts
new file mode 100644
index 000000000..0cc91e484
--- /dev/null
+++ b/client/src/app/+my-library/my-library.component.ts
@@ -0,0 +1,76 @@
1import { Component, OnInit } from '@angular/core'
2import { AuthService, AuthUser, ScreenService, ServerService } from '@app/core'
3import { ServerConfig } from '@shared/models'
4import { TopMenuDropdownParam } from '../shared/shared-main/misc/top-menu-dropdown.component'
5
6@Component({
7 templateUrl: './my-library.component.html',
8 styleUrls: [ './my-library.component.scss' ]
9})
10export class MyLibraryComponent implements OnInit {
11 menuEntries: TopMenuDropdownParam[] = []
12 user: AuthUser
13
14 private serverConfig: ServerConfig
15
16 constructor (
17 private serverService: ServerService,
18 private authService: AuthService,
19 private screenService: ScreenService
20 ) { }
21
22 get isBroadcastMessageDisplayed () {
23 return this.screenService.isBroadcastMessageDisplayed
24 }
25
26 ngOnInit (): void {
27 this.serverConfig = this.serverService.getTmpConfig()
28 this.serverService.getConfig()
29 .subscribe(config => this.serverConfig = config)
30
31 this.user = this.authService.getUser()
32
33 this.authService.userInformationLoaded.subscribe(
34 () => this.buildMenu()
35 )
36 }
37
38 isVideoImportEnabled () {
39 const importConfig = this.serverConfig.import.videos
40
41 return importConfig.http.enabled || importConfig.torrent.enabled
42 }
43
44 private buildMenu () {
45 this.menuEntries = [
46 {
47 label: $localize`Channels`,
48 routerLink: '/my-library/video-channels'
49 }
50 ]
51
52 if (this.user.canSeeVideosLink) {
53 this.menuEntries.push({
54 label: $localize`Videos`,
55 routerLink: '/my-library/videos'
56 })
57 }
58
59 this.menuEntries = this.menuEntries.concat([
60 {
61 label: $localize`Playlists`,
62 routerLink: '/my-library/video-playlists'
63 },
64
65 {
66 label: $localize`Subscriptions`,
67 routerLink: '/my-library/subscriptions'
68 },
69
70 {
71 label: $localize`History`,
72 routerLink: '/my-library/history/videos'
73 }
74 ])
75 }
76}
diff --git a/client/src/app/+my-library/my-library.module.ts b/client/src/app/+my-library/my-library.module.ts
new file mode 100644
index 000000000..bf791952c
--- /dev/null
+++ b/client/src/app/+my-library/my-library.module.ts
@@ -0,0 +1,79 @@
1import { AutoCompleteModule } from 'primeng/autocomplete'
2import { InputSwitchModule } from 'primeng/inputswitch'
3import { TableModule } from 'primeng/table'
4import { DragDropModule } from '@angular/cdk/drag-drop'
5import { NgModule } from '@angular/core'
6import { SharedAbuseListModule } from '@app/shared/shared-abuse-list'
7import { SharedFormModule } from '@app/shared/shared-forms'
8import { SharedGlobalIconModule } from '@app/shared/shared-icons'
9import { SharedMainModule } from '@app/shared/shared-main'
10import { SharedModerationModule } from '@app/shared/shared-moderation'
11import { SharedShareModal } from '@app/shared/shared-share-modal'
12import { SharedUserInterfaceSettingsModule } from '@app/shared/shared-user-settings'
13import { SharedUserSubscriptionModule } from '@app/shared/shared-user-subscription/shared-user-subscription.module'
14import { SharedVideoLiveModule } from '@app/shared/shared-video-live'
15import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
16import { SharedVideoPlaylistModule } from '@app/shared/shared-video-playlist/shared-video-playlist.module'
17import { MyHistoryComponent } from './my-history/my-history.component'
18import { MyLibraryRoutingModule } from './my-library-routing.module'
19import { MyLibraryComponent } from './my-library.component'
20import { MyAcceptOwnershipComponent } from './my-ownership/my-accept-ownership/my-accept-ownership.component'
21import { MyOwnershipComponent } from './my-ownership/my-ownership.component'
22import { MySubscriptionsComponent } from './my-subscriptions/my-subscriptions.component'
23import { MyVideoImportsComponent } from './my-video-imports/my-video-imports.component'
24import { MyVideoPlaylistCreateComponent } from './my-video-playlists/my-video-playlist-create.component'
25import { MyVideoPlaylistElementsComponent } from './my-video-playlists/my-video-playlist-elements.component'
26import { MyVideoPlaylistUpdateComponent } from './my-video-playlists/my-video-playlist-update.component'
27import { MyVideoPlaylistsComponent } from './my-video-playlists/my-video-playlists.component'
28import { VideoChangeOwnershipComponent } from './my-videos/modals/video-change-ownership.component'
29import { MyVideosComponent } from './my-videos/my-videos.component'
30
31@NgModule({
32 imports: [
33 MyLibraryRoutingModule,
34
35 AutoCompleteModule,
36 TableModule,
37 InputSwitchModule,
38 DragDropModule,
39
40 SharedMainModule,
41 SharedFormModule,
42 SharedModerationModule,
43 SharedVideoMiniatureModule,
44 SharedUserSubscriptionModule,
45 SharedVideoPlaylistModule,
46 SharedUserInterfaceSettingsModule,
47 SharedGlobalIconModule,
48 SharedAbuseListModule,
49 SharedShareModal,
50 SharedVideoLiveModule
51 ],
52
53 declarations: [
54 MyLibraryComponent,
55
56 MyVideosComponent,
57
58 VideoChangeOwnershipComponent,
59
60 MyOwnershipComponent,
61 MyAcceptOwnershipComponent,
62 MyVideoImportsComponent,
63 MySubscriptionsComponent,
64 MyHistoryComponent,
65
66 MyVideoPlaylistCreateComponent,
67 MyVideoPlaylistUpdateComponent,
68 MyVideoPlaylistsComponent,
69 MyVideoPlaylistElementsComponent
70 ],
71
72 exports: [
73 MyLibraryComponent
74 ],
75
76 providers: []
77})
78export class MyLibraryModule {
79}
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.html
index def1cbab6..def1cbab6 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html
+++ b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.html
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.scss b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.scss
index c7357f62d..c7357f62d 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.scss
+++ b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.scss
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.ts
index 4c4436755..587a455f0 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
+++ b/client/src/app/+my-library/my-ownership/my-accept-ownership/my-accept-ownership.component.ts
@@ -7,11 +7,11 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
7import { VideoChangeOwnership, VideoChannel } from '@shared/models' 7import { VideoChangeOwnership, VideoChannel } from '@shared/models'
8 8
9@Component({ 9@Component({
10 selector: 'my-account-accept-ownership', 10 selector: 'my-accept-ownership',
11 templateUrl: './my-account-accept-ownership.component.html', 11 templateUrl: './my-accept-ownership.component.html',
12 styleUrls: [ './my-account-accept-ownership.component.scss' ] 12 styleUrls: [ './my-accept-ownership.component.scss' ]
13}) 13})
14export class MyAccountAcceptOwnershipComponent extends FormReactive implements OnInit { 14export class MyAcceptOwnershipComponent extends FormReactive implements OnInit {
15 @Output() accepted = new EventEmitter<void>() 15 @Output() accepted = new EventEmitter<void>()
16 16
17 @ViewChild('modal', { static: true }) modal: ElementRef 17 @ViewChild('modal', { static: true }) modal: ElementRef
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html b/client/src/app/+my-library/my-ownership/my-ownership.component.html
index fd2163fb4..6bf562986 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html
+++ b/client/src/app/+my-library/my-ownership/my-ownership.component.html
@@ -87,4 +87,4 @@
87 </ng-template> 87 </ng-template>
88</p-table> 88</p-table>
89 89
90<my-account-accept-ownership #myAccountAcceptOwnershipComponent (accepted)="accepted()"></my-account-accept-ownership> 90<my-accept-ownership #myAcceptOwnershipComponent (accepted)="accepted()"></my-accept-ownership>
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.scss b/client/src/app/+my-library/my-ownership/my-ownership.component.scss
index 7cac9c9f3..7cac9c9f3 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.scss
+++ b/client/src/app/+my-library/my-ownership/my-ownership.component.scss
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts b/client/src/app/+my-library/my-ownership/my-ownership.component.ts
index 7473470aa..e1aca65f6 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
+++ b/client/src/app/+my-library/my-ownership/my-ownership.component.ts
@@ -1,23 +1,21 @@
1import { SortMeta } from 'primeng/api' 1import { SortMeta } from 'primeng/api'
2import { Component, OnInit, ViewChild } from '@angular/core' 2import { Component, OnInit, ViewChild } from '@angular/core'
3import { Notifier, RestPagination, RestTable } from '@app/core' 3import { Notifier, RestPagination, RestTable } from '@app/core'
4import { VideoOwnershipService, Actor, Video, Account } from '@app/shared/shared-main' 4import { Account, Actor, VideoOwnershipService } from '@app/shared/shared-main'
5import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '@shared/models' 5import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '@shared/models'
6import { MyAccountAcceptOwnershipComponent } from './my-account-accept-ownership/my-account-accept-ownership.component' 6import { MyAcceptOwnershipComponent } from './my-accept-ownership/my-accept-ownership.component'
7import { getAbsoluteAPIUrl } from '@app/helpers'
8 7
9@Component({ 8@Component({
10 selector: 'my-account-ownership', 9 templateUrl: './my-ownership.component.html',
11 templateUrl: './my-account-ownership.component.html', 10 styleUrls: [ './my-ownership.component.scss' ]
12 styleUrls: [ './my-account-ownership.component.scss' ]
13}) 11})
14export class MyAccountOwnershipComponent extends RestTable implements OnInit { 12export class MyOwnershipComponent extends RestTable implements OnInit {
15 videoChangeOwnerships: VideoChangeOwnership[] = [] 13 videoChangeOwnerships: VideoChangeOwnership[] = []
16 totalRecords = 0 14 totalRecords = 0
17 sort: SortMeta = { field: 'createdAt', order: -1 } 15 sort: SortMeta = { field: 'createdAt', order: -1 }
18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 16 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
19 17
20 @ViewChild('myAccountAcceptOwnershipComponent', { static: true }) myAccountAcceptOwnershipComponent: MyAccountAcceptOwnershipComponent 18 @ViewChild('myAcceptOwnershipComponent', { static: true }) myAccountAcceptOwnershipComponent: MyAcceptOwnershipComponent
21 19
22 constructor ( 20 constructor (
23 private notifier: Notifier, 21 private notifier: Notifier,
@@ -31,7 +29,7 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
31 } 29 }
32 30
33 getIdentifier () { 31 getIdentifier () {
34 return 'MyAccountOwnershipComponent' 32 return 'MyOwnershipComponent'
35 } 33 }
36 34
37 getStatusClass (status: VideoChangeOwnershipStatus) { 35 getStatusClass (status: VideoChangeOwnershipStatus) {
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html
index 6ab3826ba..6ab3826ba 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html
+++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.html
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.scss b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss
index 5ead45dd8..5ead45dd8 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.scss
+++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.scss
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts
index 994fe5142..3b748eccf 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
+++ b/client/src/app/+my-library/my-subscriptions/my-subscriptions.component.ts
@@ -1,16 +1,15 @@
1import { Subject } from 'rxjs' 1import { Subject } from 'rxjs'
2import { debounceTime } from 'rxjs/operators'
2import { Component, OnInit } from '@angular/core' 3import { Component, OnInit } from '@angular/core'
3import { ComponentPagination, Notifier } from '@app/core' 4import { ComponentPagination, Notifier } from '@app/core'
4import { VideoChannel } from '@app/shared/shared-main' 5import { VideoChannel } from '@app/shared/shared-main'
5import { UserSubscriptionService } from '@app/shared/shared-user-subscription' 6import { UserSubscriptionService } from '@app/shared/shared-user-subscription'
6import { debounceTime } from 'rxjs/operators'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-subscriptions', 9 templateUrl: './my-subscriptions.component.html',
10 templateUrl: './my-account-subscriptions.component.html', 10 styleUrls: [ './my-subscriptions.component.scss' ]
11 styleUrls: [ './my-account-subscriptions.component.scss' ]
12}) 11})
13export class MyAccountSubscriptionsComponent implements OnInit { 12export class MySubscriptionsComponent implements OnInit {
14 videoChannels: VideoChannel[] = [] 13 videoChannels: VideoChannel[] = []
15 14
16 pagination: ComponentPagination = { 15 pagination: ComponentPagination = {
diff --git a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.html b/client/src/app/+my-library/my-video-imports/my-video-imports.component.html
index 1d3a45f76..1d3a45f76 100644
--- a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.html
+++ b/client/src/app/+my-library/my-video-imports/my-video-imports.component.html
diff --git a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.scss b/client/src/app/+my-library/my-video-imports/my-video-imports.component.scss
index a93c28028..a93c28028 100644
--- a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.scss
+++ b/client/src/app/+my-library/my-video-imports/my-video-imports.component.scss
diff --git a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts b/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts
index 9dd5ef142..d6d7d7a1b 100644
--- a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts
+++ b/client/src/app/+my-library/my-video-imports/my-video-imports.component.ts
@@ -5,11 +5,10 @@ import { VideoImportService } from '@app/shared/shared-main'
5import { VideoImport, VideoImportState } from '@shared/models' 5import { VideoImport, VideoImportState } from '@shared/models'
6 6
7@Component({ 7@Component({
8 selector: 'my-account-video-imports', 8 templateUrl: './my-video-imports.component.html',
9 templateUrl: './my-account-video-imports.component.html', 9 styleUrls: [ './my-video-imports.component.scss' ]
10 styleUrls: [ './my-account-video-imports.component.scss' ]
11}) 10})
12export class MyAccountVideoImportsComponent extends RestTable implements OnInit { 11export class MyVideoImportsComponent extends RestTable implements OnInit {
13 videoImports: VideoImport[] = [] 12 videoImports: VideoImport[] = []
14 totalRecords = 0 13 totalRecords = 0
15 sort: SortMeta = { field: 'createdAt', order: 1 } 14 sort: SortMeta = { field: 'createdAt', order: 1 }
@@ -27,7 +26,7 @@ export class MyAccountVideoImportsComponent extends RestTable implements OnInit
27 } 26 }
28 27
29 getIdentifier () { 28 getIdentifier () {
30 return 'MyAccountVideoImportsComponent' 29 return 'MyVideoImportsComponent'
31 } 30 }
32 31
33 getVideoImportStateClass (state: VideoImportState) { 32 getVideoImportStateClass (state: VideoImportState) {
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlist-create.component.ts
index 7a80aaa92..5abea54b0 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-create.component.ts
@@ -13,14 +13,13 @@ import { FormValidatorService } from '@app/shared/shared-forms'
13import { VideoPlaylistService } from '@app/shared/shared-video-playlist' 13import { VideoPlaylistService } from '@app/shared/shared-video-playlist'
14import { VideoPlaylistCreate } from '@shared/models/videos/playlist/video-playlist-create.model' 14import { VideoPlaylistCreate } from '@shared/models/videos/playlist/video-playlist-create.model'
15import { VideoPlaylistPrivacy } from '@shared/models/videos/playlist/video-playlist-privacy.model' 15import { VideoPlaylistPrivacy } from '@shared/models/videos/playlist/video-playlist-privacy.model'
16import { MyAccountVideoPlaylistEdit } from './my-account-video-playlist-edit' 16import { MyVideoPlaylistEdit } from './my-video-playlist-edit'
17 17
18@Component({ 18@Component({
19 selector: 'my-account-video-playlist-create', 19 templateUrl: './my-video-playlist-edit.component.html',
20 templateUrl: './my-account-video-playlist-edit.component.html', 20 styleUrls: [ './my-video-playlist-edit.component.scss' ]
21 styleUrls: [ './my-account-video-playlist-edit.component.scss' ]
22}) 21})
23export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylistEdit implements OnInit { 22export class MyVideoPlaylistCreateComponent extends MyVideoPlaylistEdit implements OnInit {
24 error: string 23 error: string
25 24
26 constructor ( 25 constructor (
@@ -75,7 +74,7 @@ export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylis
75 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe( 74 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe(
76 () => { 75 () => {
77 this.notifier.success($localize`Playlist ${videoPlaylistCreate.displayName} created.`) 76 this.notifier.success($localize`Playlist ${videoPlaylistCreate.displayName} created.`)
78 this.router.navigate([ '/my-account', 'video-playlists' ]) 77 this.router.navigate([ '/my-library', 'video-playlists' ])
79 }, 78 },
80 79
81 err => this.error = err.message 80 err => this.error = err.message
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.html
index 56060359a..0d8d2a447 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.html
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.html
@@ -1,7 +1,7 @@
1<nav aria-label="breadcrumb"> 1<nav aria-label="breadcrumb">
2 <ol class="breadcrumb"> 2 <ol class="breadcrumb">
3 <li class="breadcrumb-item"> 3 <li class="breadcrumb-item">
4 <a routerLink="/my-account/video-playlists" i18n>My Playlists</a> 4 <a routerLink="/my-library/video-playlists" i18n>My Playlists</a>
5 </li> 5 </li>
6 6
7 <ng-container *ngIf="isCreation()"> 7 <ng-container *ngIf="isCreation()">
@@ -10,7 +10,7 @@
10 <ng-container *ngIf="!isCreation()"> 10 <ng-container *ngIf="!isCreation()">
11 <li class="breadcrumb-item active" i18n>Edit</li> 11 <li class="breadcrumb-item active" i18n>Edit</li>
12 <li class="breadcrumb-item active" aria-current="page"> 12 <li class="breadcrumb-item active" aria-current="page">
13 <a *ngIf="videoPlaylistToUpdate" [routerLink]="[ '/my-account/video-playlists/update', videoPlaylistToUpdate?.uuid ]">{{ videoPlaylistToUpdate?.displayName }}</a> 13 <a *ngIf="videoPlaylistToUpdate" [routerLink]="[ '/my-library/video-playlists/update', videoPlaylistToUpdate?.uuid ]">{{ videoPlaylistToUpdate?.displayName }}</a>
14 </li> 14 </li>
15 </ng-container> 15 </ng-container>
16 </ol> 16 </ol>
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.scss b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.scss
index 08fab1101..08fab1101 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.component.scss
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.component.scss
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.ts
index 774d58c90..40ba23e75 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-edit.ts
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-edit.ts
@@ -2,7 +2,7 @@ import { FormReactive, SelectChannelItem } from '@app/shared/shared-forms'
2import { VideoConstant, VideoPlaylistPrivacy } from '@shared/models' 2import { VideoConstant, VideoPlaylistPrivacy } from '@shared/models'
3import { VideoPlaylist } from '@shared/models/videos/playlist/video-playlist.model' 3import { VideoPlaylist } from '@shared/models/videos/playlist/video-playlist.model'
4 4
5export abstract class MyAccountVideoPlaylistEdit extends FormReactive { 5export abstract class MyVideoPlaylistEdit extends FormReactive {
6 // Declare it here to avoid errors in create template 6 // Declare it here to avoid errors in create template
7 videoPlaylistToUpdate: VideoPlaylist 7 videoPlaylistToUpdate: VideoPlaylist
8 userVideoChannels: SelectChannelItem[] = [] 8 userVideoChannels: SelectChannelItem[] = []
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html
index 09b4c8a1b..09b4c8a1b 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.html
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss
index de7e1993f..de7e1993f 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.scss
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.ts
index f6cdf1067..a8fdf6e29 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-elements.component.ts
@@ -9,11 +9,10 @@ import { VideoPlaylist, VideoPlaylistElement, VideoPlaylistService } from '@app/
9import { VideoPlaylistType } from '@shared/models' 9import { VideoPlaylistType } from '@shared/models'
10 10
11@Component({ 11@Component({
12 selector: 'my-account-video-playlist-elements', 12 templateUrl: './my-video-playlist-elements.component.html',
13 templateUrl: './my-account-video-playlist-elements.component.html', 13 styleUrls: [ './my-video-playlist-elements.component.scss' ]
14 styleUrls: [ './my-account-video-playlist-elements.component.scss' ]
15}) 14})
16export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestroy { 15export class MyVideoPlaylistElementsComponent implements OnInit, OnDestroy {
17 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent 16 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent
18 17
19 playlistElements: VideoPlaylistElement[] = [] 18 playlistElements: VideoPlaylistElement[] = []
@@ -47,7 +46,7 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
47 { 46 {
48 label: $localize`Update playlist`, 47 label: $localize`Update playlist`,
49 iconName: 'edit', 48 iconName: 'edit',
50 linkBuilder: playlist => [ '/my-account', 'video-playlists', 'update', playlist.uuid ] 49 linkBuilder: playlist => [ '/my-library', 'video-playlists', 'update', playlist.uuid ]
51 }, 50 },
52 { 51 {
53 label: $localize`Delete playlist`, 52 label: $localize`Delete playlist`,
@@ -132,7 +131,7 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
132 this.videoPlaylistService.removeVideoPlaylist(videoPlaylist) 131 this.videoPlaylistService.removeVideoPlaylist(videoPlaylist)
133 .subscribe( 132 .subscribe(
134 () => { 133 () => {
135 this.router.navigate([ '/my-account', 'video-playlists' ]) 134 this.router.navigate([ '/my-library', 'video-playlists' ])
136 this.notifier.success($localize`Playlist ${videoPlaylist.displayName} deleted.`) 135 this.notifier.success($localize`Playlist ${videoPlaylist.displayName} deleted.`)
137 }, 136 },
138 137
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlist-update.component.ts
index fefc6d607..532423ba2 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlist-update.component.ts
@@ -14,14 +14,13 @@ import {
14import { FormValidatorService } from '@app/shared/shared-forms' 14import { FormValidatorService } from '@app/shared/shared-forms'
15import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' 15import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist'
16import { VideoPlaylistUpdate } from '@shared/models' 16import { VideoPlaylistUpdate } from '@shared/models'
17import { MyAccountVideoPlaylistEdit } from './my-account-video-playlist-edit' 17import { MyVideoPlaylistEdit } from './my-video-playlist-edit'
18 18
19@Component({ 19@Component({
20 selector: 'my-account-video-playlist-update', 20 templateUrl: './my-video-playlist-edit.component.html',
21 templateUrl: './my-account-video-playlist-edit.component.html', 21 styleUrls: [ './my-video-playlist-edit.component.scss' ]
22 styleUrls: [ './my-account-video-playlist-edit.component.scss' ]
23}) 22})
24export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylistEdit implements OnInit, OnDestroy { 23export class MyVideoPlaylistUpdateComponent extends MyVideoPlaylistEdit implements OnInit, OnDestroy {
25 error: string 24 error: string
26 videoPlaylistToUpdate: VideoPlaylist 25 videoPlaylistToUpdate: VideoPlaylist
27 26
@@ -96,7 +95,7 @@ export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylis
96 this.videoPlaylistService.updateVideoPlaylist(this.videoPlaylistToUpdate, videoPlaylistUpdate).subscribe( 95 this.videoPlaylistService.updateVideoPlaylist(this.videoPlaylistToUpdate, videoPlaylistUpdate).subscribe(
97 () => { 96 () => {
98 this.notifier.success($localize`Playlist ${videoPlaylistUpdate.displayName} updated.`) 97 this.notifier.success($localize`Playlist ${videoPlaylistUpdate.displayName} updated.`)
99 this.router.navigate([ '/my-account', 'video-playlists' ]) 98 this.router.navigate([ '/my-library', 'video-playlists' ])
100 }, 99 },
101 100
102 err => this.error = err.message 101 err => this.error = err.message
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html
index afcf6a084..afcf6a084 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.html
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss
index 2b7c88246..2b7c88246 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.scss
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.scss
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts
index 1e569c0b6..f6d394923 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts
+++ b/client/src/app/+my-library/my-video-playlists/my-video-playlists.component.ts
@@ -6,11 +6,10 @@ import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-pl
6import { VideoPlaylistType } from '@shared/models' 6import { VideoPlaylistType } from '@shared/models'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-video-playlists', 9 templateUrl: './my-video-playlists.component.html',
10 templateUrl: './my-account-video-playlists.component.html', 10 styleUrls: [ './my-video-playlists.component.scss' ]
11 styleUrls: [ './my-account-video-playlists.component.scss' ]
12}) 11})
13export class MyAccountVideoPlaylistsComponent implements OnInit { 12export class MyVideoPlaylistsComponent implements OnInit {
14 videoPlaylistsSearch: string 13 videoPlaylistsSearch: string
15 videoPlaylists: VideoPlaylist[] = [] 14 videoPlaylists: VideoPlaylist[] = []
16 videoPlaylistSearchChanged = new Subject<string>() 15 videoPlaylistSearchChanged = new Subject<string>()
diff --git a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.html b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.html
index c7c5a0b69..c7c5a0b69 100644
--- a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.html
+++ b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.html
diff --git a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.scss b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.scss
index a79fec179..a79fec179 100644
--- a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.scss
+++ b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.scss
diff --git a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.ts b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.ts
index 84237dee1..84237dee1 100644
--- a/client/src/app/+my-account/my-account-videos/modals/video-change-ownership.component.ts
+++ b/client/src/app/+my-library/my-videos/modals/video-change-ownership.component.ts
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-library/my-videos/my-videos.component.html
index aa5b284e7..977f7b03b 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-library/my-videos/my-videos.component.html
@@ -4,6 +4,18 @@
4 <ng-container i18n>My videos</ng-container> 4 <ng-container i18n>My videos</ng-container>
5 <span class="badge badge-secondary"> {{ pagination.totalItems }}</span> 5 <span class="badge badge-secondary"> {{ pagination.totalItems }}</span>
6 </span> 6 </span>
7
8 <div>
9 <a routerLink="/my-library/video-imports" class="button-link">
10 <my-global-icon iconName="cloud-download" aria-hidden="true"></my-global-icon>
11 <ng-container i18n>My imports</ng-container>
12 </a>
13
14 <a routerLink="/my-library/ownership" class="button-link">
15 <my-global-icon iconName="users" aria-hidden="true"></my-global-icon>
16 <ng-container i18n>Ownership changes</ng-container>
17 </a>
18 </div>
7</h1> 19</h1>
8 20
9<div class="videos-header d-flex justify-content-between"> 21<div class="videos-header d-flex justify-content-between">
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-library/my-videos/my-videos.component.scss
index 246f46320..59fc5fe80 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
+++ b/client/src/app/+my-library/my-videos/my-videos.component.scss
@@ -5,6 +5,21 @@ input[type=text] {
5 @include peertube-input-text(300px); 5 @include peertube-input-text(300px);
6} 6}
7 7
8h1 {
9 display: flex;
10 justify-content: space-between;
11
12 .button-link {
13 @include peertube-button-link;
14 @include grey-button;
15 @include button-with-icon(18px, 3px, -1px);
16
17 &:not(:last-child) {
18 margin-right: 10px;
19 }
20 }
21}
22
8.action-button-delete-selection { 23.action-button-delete-selection {
9 display: inline-block; 24 display: inline-block;
10 25
@@ -50,52 +65,48 @@ input[type=text] {
50 align-self: flex-end; 65 align-self: flex-end;
51} 66}
52 67
53my-delete-button,
54my-edit-button { 68my-edit-button {
55 margin-right: 10px; 69 margin-right: 10px;
56} 70}
57 71
58@media screen and (max-width: $small-view) { 72@media screen and (max-width: $small-view) {
73 h1 {
74 flex-direction: column;
75
76 > span,
77 .button-link {
78 margin-bottom: 10px;
79 }
80 }
81
59 .action-button { 82 .action-button {
60 flex-direction: column; 83 flex-direction: column;
61 align-self: center; 84 align-self: center;
85 align-items: center;
62 margin-left: 0px; 86 margin-left: 0px;
63 } 87 }
64 88
65 ::ng-deep {
66 .video-miniature {
67 align-items: center;
68
69 .video-bottom,
70 .video-bottom .video-miniature-information {
71 /* same width than a.video-thumbnail */
72 max-width: $video-thumbnail-width !important;
73 }
74 }
75 }
76
77 my-delete-button,
78 my-edit-button { 89 my-edit-button {
79 margin-right: 0px; 90 margin: 15px 0 5px 0;
91 width: 100%;
92 text-align: center;
80 93
81 ::ng-deep { 94 ::ng-deep {
82 span, a { 95 .action-button {
83 margin-right: 0px; 96 /* same width than a.video-thumbnail */
97 width: $video-thumbnail-width;
84 } 98 }
85 } 99 }
86 } 100 }
87 101
88 my-delete-button, 102 ::ng-deep {
89 my-edit-button, 103 .video-miniature {
90 my-button { 104 align-items: center;
91 margin-top: 15px;
92 width: 100%;
93 text-align: center;
94 105
95 ::ng-deep { 106 .video-bottom,
96 .action-button { 107 .video-bottom .video-miniature-information {
97 /* same width than a.video-thumbnail */ 108 /* same width than a.video-thumbnail */
98 width: $video-thumbnail-width; 109 max-width: $video-thumbnail-width !important;
99 } 110 }
100 } 111 }
101 } 112 }
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-library/my-videos/my-videos.component.ts
index 84f022ad2..e89bb12e1 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
+++ b/client/src/app/+my-library/my-videos/my-videos.component.ts
@@ -12,11 +12,10 @@ import { VideoSortField } from '@shared/models'
12import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component' 12import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component'
13 13
14@Component({ 14@Component({
15 selector: 'my-account-videos', 15 templateUrl: './my-videos.component.html',
16 templateUrl: './my-account-videos.component.html', 16 styleUrls: [ './my-videos.component.scss' ]
17 styleUrls: [ './my-account-videos.component.scss' ]
18}) 17})
19export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { 18export class MyVideosComponent implements OnInit, DisableForReuseHook {
20 @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent 19 @ViewChild('videosSelection', { static: true }) videosSelection: VideosSelectionComponent
21 @ViewChild('videoChangeOwnershipModal', { static: true }) videoChangeOwnershipModal: VideoChangeOwnershipComponent 20 @ViewChild('videoChangeOwnershipModal', { static: true }) videoChangeOwnershipModal: VideoChangeOwnershipComponent
22 @ViewChild('liveStreamInformationModal', { static: true }) liveStreamInformationModal: LiveStreamInformationComponent 21 @ViewChild('liveStreamInformationModal', { static: true }) liveStreamInformationModal: LiveStreamInformationComponent
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html
index 43b5cd92e..4b0d12b6e 100644
--- a/client/src/app/+video-channels/video-channels.component.html
+++ b/client/src/app/+video-channels/video-channels.component.html
@@ -18,7 +18,7 @@
18 </div> 18 </div>
19 19
20 <div class="right-buttons"> 20 <div class="right-buttons">
21 <a *ngIf="isChannelManageable && !isInSmallView" [routerLink]="[ '/my-account/video-channels/update', videoChannel.nameWithHost ]" class="btn btn-outline-tertiary mr-2" i18n> 21 <a *ngIf="isChannelManageable && !isInSmallView" [routerLink]="[ '/my-library/video-channels/update', videoChannel.nameWithHost ]" class="btn btn-outline-tertiary mr-2" i18n>
22 Manage channel 22 Manage channel
23 </a> 23 </a>
24 <my-subscribe-button #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button> 24 <my-subscribe-button #subscribeButton [videoChannels]="[videoChannel]"></my-subscribe-button>
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts
index 64e887987..caa7af90a 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts
@@ -128,7 +128,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
128 this.isUpdatingVideo = false 128 this.isUpdatingVideo = false
129 this.notifier.success($localize`Video to import updated.`) 129 this.notifier.success($localize`Video to import updated.`)
130 130
131 this.router.navigate([ '/my-account', 'video-imports' ]) 131 this.router.navigate([ '/my-library', 'video-imports' ])
132 }, 132 },
133 133
134 err => { 134 err => {
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
index 47f59a5d0..5ca753eaf 100644
--- a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
+++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
@@ -138,7 +138,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
138 this.isUpdatingVideo = false 138 this.isUpdatingVideo = false
139 this.notifier.success($localize`Video to import updated.`) 139 this.notifier.success($localize`Video to import updated.`)
140 140
141 this.router.navigate([ '/my-account', 'video-imports' ]) 141 this.router.navigate([ '/my-library', 'video-imports' ])
142 }, 142 },
143 143
144 err => { 144 err => {
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 b02988169..6988c574b 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
@@ -34,7 +34,7 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement
34 34
35 this.titlePage = $localize`Videos from your subscriptions` 35 this.titlePage = $localize`Videos from your subscriptions`
36 this.actions.push({ 36 this.actions.push({
37 routerLink: '/my-account/subscriptions', 37 routerLink: '/my-library/subscriptions',
38 label: $localize`Subscriptions`, 38 label: $localize`Subscriptions`,
39 iconName: 'cog' 39 iconName: 'cog'
40 }) 40 })
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index d3cdcefea..bcae29c9a 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -18,6 +18,10 @@ const routes: Routes = [
18 loadChildren: () => import('./+my-account/my-account.module').then(m => m.MyAccountModule) 18 loadChildren: () => import('./+my-account/my-account.module').then(m => m.MyAccountModule)
19 }, 19 },
20 { 20 {
21 path: 'my-library',
22 loadChildren: () => import('./+my-library/my-library.module').then(m => m.MyLibraryModule)
23 },
24 {
21 path: 'verify-account', 25 path: 'verify-account',
22 loadChildren: () => import('./+signup/+verify-account/verify-account.module').then(m => m.VerifyAccountModule) 26 loadChildren: () => import('./+signup/+verify-account/verify-account.module').then(m => m.VerifyAccountModule)
23 }, 27 },
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 10e2c2c58..3410c5a6f 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -62,15 +62,15 @@ export class AuthService {
62 return false 62 return false
63 }, undefined, $localize`Go to my subscriptions`), 63 }, undefined, $localize`Go to my subscriptions`),
64 new Hotkey('m v', (event: KeyboardEvent): boolean => { 64 new Hotkey('m v', (event: KeyboardEvent): boolean => {
65 this.router.navigate([ '/my-account/videos' ]) 65 this.router.navigate([ '/my-library/videos' ])
66 return false 66 return false
67 }, undefined, $localize`Go to my videos`), 67 }, undefined, $localize`Go to my videos`),
68 new Hotkey('m i', (event: KeyboardEvent): boolean => { 68 new Hotkey('m i', (event: KeyboardEvent): boolean => {
69 this.router.navigate([ '/my-account/video-imports' ]) 69 this.router.navigate([ '/my-library/video-imports' ])
70 return false 70 return false
71 }, undefined, $localize`Go to my imports`), 71 }, undefined, $localize`Go to my imports`),
72 new Hotkey('m c', (event: KeyboardEvent): boolean => { 72 new Hotkey('m c', (event: KeyboardEvent): boolean => {
73 this.router.navigate([ '/my-account/video-channels' ]) 73 this.router.navigate([ '/my-library/video-channels' ])
74 return false 74 return false
75 }, undefined, $localize`Go to my channels`) 75 }, undefined, $localize`Go to my channels`)
76 ] 76 ]
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html
index 2011899d3..a4b4f26d0 100644
--- a/client/src/app/menu/menu.component.html
+++ b/client/src/app/menu/menu.component.html
@@ -1,98 +1,106 @@
1<div class="menu-wrapper"> 1<div class="menu-wrapper">
2 <menu [ngClass]="{ 'logged-in': isLoggedIn }"> 2 <menu [ngClass]="{ 'is-logged-in': isLoggedIn }">
3 <div class="top-menu"> 3 <div class="top-menu">
4 <div *ngIf="isLoggedIn" class="logged-in-block"> 4 <div *ngIf="isLoggedIn" class="logged-in-block">
5 <my-avatar-notification [user]="user" (navigate)="onSameUrlRestoreScrollPosition($event)"></my-avatar-notification> 5 <div>
6 <my-avatar-notification [user]="user" (navigate)="onSameUrlRestoreScrollPosition($event)"></my-avatar-notification>
6 7
7 <div class="logged-in-info"> 8 <div class="logged-in-info">
8 <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="logged-in-display-name">{{ user.account?.displayName }}</a> 9 <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="logged-in-display-name">{{ user.account?.displayName }}</a>
9 <a *ngIf="!user.account" routerLink="/my-account/settings" class="logged-in-display-name">{{ user.account?.displayName }}</a> 10 <a *ngIf="!user.account" routerLink="/my-account/settings" class="logged-in-display-name">{{ user.account?.displayName }}</a>
10 11
11 <div class="logged-in-username">{{ user.username }}</div> 12 <div class="logged-in-username">@{{ user.username }}</div>
12 </div> 13 </div>
13
14 <div class="logged-in-more" ngbDropdown [placement]="placement" container="body" autoClose="outside">
15 <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon>
16
17 <div ngbDropdownMenu>
18 <a *ngIf="user.account" ngbDropdownItem ngbDropdownToggle class="dropdown-item" [routerLink]="[ '/accounts', user.account.nameWithHost ]">
19 <my-global-icon iconName="go" aria-hidden="true"></my-global-icon> <ng-container i18n>Public profile</ng-container>
20 </a>
21
22 <div class="dropdown-divider"></div>
23
24 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings"
25 #settingsLink (click)="onSameUrlRestoreScrollPosition(settingsLink)">
26 <my-global-icon iconName="user" aria-hidden="true"></my-global-icon> <ng-container i18n>Account settings</ng-container>
27 </a>
28
29 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/video-channels"
30 #channelsLink (click)="onSameUrlRestoreScrollPosition(channelsLink)">
31 <my-global-icon iconName="channel" aria-hidden="true"></my-global-icon> <ng-container i18n>Channels settings</ng-container>
32 </a>
33
34 <div class="dropdown-divider"></div>
35
36 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openLanguageChooser()">
37 <my-global-icon iconName="language" aria-hidden="true"></my-global-icon>
38 <span i18n>Interface:</span>
39 <span class="ml-auto text-muted">{{ language }}</span>
40 </a>
41
42 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings" fragment="video-languages-subtitles"
43 #settingsLanguagesSubtitles (click)="onSameUrlRestoreScrollPosition(settingsLanguagesSubtitles)">
44 <my-global-icon iconName="video-lang" aria-hidden="true"></my-global-icon>
45 <span i18n>Videos:</span>
46 <span class="ml-auto text-muted">{{ videoLanguages.join(', ') }}</span>
47 </a>
48
49 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings"
50 fragment="video-sensitive-content-policy" #settingsSensitiveContentPolicy
51 (click)="onSameUrlRestoreScrollPosition(settingsSensitiveContentPolicy)">
52 <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy === 'display' }" iconName="sensitive" aria-hidden="true"></my-global-icon>
53 <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy !== 'display' }" iconName="unsensitive" aria-hidden="true"></my-global-icon>
54 <span i18n>Sensitive:</span>
55 <span class="ml-auto text-muted">{{ nsfwPolicy }}</span>
56 </a>
57
58 <a ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()">
59 <my-global-icon iconName="p2p" aria-hidden="true"></my-global-icon>
60 <ng-container i18n>Help share videos</ng-container>
61 <input type="checkbox" [checked]="user.webTorrentEnabled"/><label class="ml-auto" for="switch">Toggle p2p</label>
62 </a>
63
64 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings"
65 #settingsMoreLink (click)="onSameUrlRestoreScrollPosition(settingsMoreLink)">
66 <my-global-icon iconName="more-horizontal" aria-hidden="true"></my-global-icon> <ng-container i18n>More account settings</ng-container>
67 </a>
68
69 <div class="dropdown-divider"></div>
70
71 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openHotkeysCheatSheet()">
72 <i class="icon icon-shortcuts" aria-hidden="true"></i> <ng-container i18n>Keyboard shortcuts</ng-container>
73 </a>
74 14
75 <a ngbDropdownItem ngbDropdownToggle (click)="logout($event)" class="dropdown-item" href="#"> 15 <div class="logged-in-more" ngbDropdown [placement]="placement" container="body" autoClose="outside">
76 <my-global-icon iconName="sign-out" aria-hidden="true"></my-global-icon> <ng-container i18n>Log out</ng-container> 16 <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon>
77 </a> 17
18 <div ngbDropdownMenu>
19 <a *ngIf="user.account" ngbDropdownItem ngbDropdownToggle class="dropdown-item" [routerLink]="[ '/accounts', user.account.nameWithHost ]">
20 <my-global-icon iconName="go" aria-hidden="true"></my-global-icon> <ng-container i18n>Public profile</ng-container>
21 </a>
22
23 <div class="dropdown-divider"></div>
24
25 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/notifications">
26 <my-global-icon iconName="inbox-full" aria-hidden="true"></my-global-icon> <ng-container i18n>My notifications</ng-container>
27 </a>
28
29 <div class="dropdown-divider"></div>
30
31 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openLanguageChooser()">
32 <my-global-icon iconName="language" aria-hidden="true"></my-global-icon>
33 <span i18n>Interface:</span>
34 <span class="ml-auto text-muted">{{ language }}</span>
35 </a>
36
37 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings" fragment="video-languages-subtitles"
38 #settingsLanguagesSubtitles (click)="onSameUrlRestoreScrollPosition(settingsLanguagesSubtitles)">
39 <my-global-icon iconName="video-lang" aria-hidden="true"></my-global-icon>
40 <span i18n>Videos:</span>
41 <span class="ml-auto text-muted">{{ videoLanguages.join(', ') }}</span>
42 </a>
43
44 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/settings"
45 fragment="video-sensitive-content-policy" #settingsSensitiveContentPolicy
46 (click)="onSameUrlRestoreScrollPosition(settingsSensitiveContentPolicy)">
47 <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy === 'display' }" iconName="sensitive" aria-hidden="true"></my-global-icon>
48 <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy !== 'display' }" iconName="unsensitive" aria-hidden="true"></my-global-icon>
49 <span i18n>Sensitive:</span>
50 <span class="ml-auto text-muted">{{ nsfwPolicy }}</span>
51 </a>
52
53 <a ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()">
54 <my-global-icon iconName="p2p" aria-hidden="true"></my-global-icon>
55 <ng-container i18n>Help share videos</ng-container>
56 <input type="checkbox" [checked]="user.webTorrentEnabled"/><label class="ml-auto" for="switch">Toggle p2p</label>
57 </a>
58
59 <div class="dropdown-divider"></div>
60
61 <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openHotkeysCheatSheet()">
62 <i class="icon icon-shortcuts" aria-hidden="true"></i> <ng-container i18n>Keyboard shortcuts</ng-container>
63 </a>
64
65 <a ngbDropdownItem ngbDropdownToggle (click)="logout($event)" class="dropdown-item" href="#">
66 <my-global-icon iconName="sign-out" aria-hidden="true"></my-global-icon> <ng-container i18n>Log out</ng-container>
67 </a>
68 </div>
78 </div> 69 </div>
79 </div> 70 </div>
71
72 <div class="logged-in-menu">
73 <a routerLink="/my-account" routerLinkActive="active" #settingsLink (click)="onSameUrlRestoreScrollPosition(settingsLink)">
74 <my-global-icon iconName="user" aria-hidden="true"></my-global-icon>
75 <ng-container i18n>My account</ng-container>
76 </a>
77
78 <a routerLink="/my-library" routerLinkActive="active" #libraryLink (click)="onSameUrlRestoreScrollPosition(libraryLink)">
79 <my-global-icon iconName="channel" aria-hidden="true"></my-global-icon>
80 <ng-container i18n>My library</ng-container>
81 </a>
82
83 <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
84 <my-global-icon iconName="cog" aria-hidden="true"></my-global-icon>
85 <ng-container i18n>Administration</ng-container>
86 </a>
87 </div>
80 </div> 88 </div>
81 89
82 <div *ngIf="!isLoggedIn" class="button-block"> 90 <div *ngIf="!isLoggedIn" class="login-buttons-block">
83 <a i18n routerLink="/login" class="login-button">Login</a> 91 <a i18n routerLink="/login" class="login-button">Login</a>
84 <a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> 92 <a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a>
85 </div> 93 </div>
86 94
87 <div *ngIf="isLoggedIn" class="panel-block"> 95 <div *ngIf="isLoggedIn" class="in-my-account">
88 <div i18n class="block-title">MY LIBRARY</div> 96 <div i18n class="block-title">IN MY ACCOUNT</div>
89 97
90 <a *ngIf="user.canSeeVideosLink" routerLink="/my-account/videos" routerLinkActive="active"> 98 <a *ngIf="user.canSeeVideosLink" routerLink="/my-library/videos" routerLinkActive="active">
91 <my-global-icon iconName="videos" aria-hidden="true"></my-global-icon> 99 <my-global-icon iconName="videos" aria-hidden="true"></my-global-icon>
92 <ng-container i18n>Videos</ng-container> 100 <ng-container i18n>Videos</ng-container>
93 </a> 101 </a>
94 102
95 <a routerLink="/my-account/video-playlists" routerLinkActive="active"> 103 <a routerLink="/my-library/video-playlists" routerLinkActive="active">
96 <my-global-icon iconName="playlists" aria-hidden="true"></my-global-icon> 104 <my-global-icon iconName="playlists" aria-hidden="true"></my-global-icon>
97 <ng-container i18n>Playlists</ng-container> 105 <ng-container i18n>Playlists</ng-container>
98 </a> 106 </a>
@@ -102,15 +110,15 @@
102 <ng-container i18n>Subscriptions</ng-container> 110 <ng-container i18n>Subscriptions</ng-container>
103 </a> 111 </a>
104 112
105 <a routerLink="/my-account/history/videos" routerLinkActive="active"> 113 <a routerLink="/my-library/history/videos" routerLinkActive="active">
106 <my-global-icon iconName="history" aria-hidden="true"></my-global-icon> 114 <my-global-icon iconName="history" aria-hidden="true"></my-global-icon>
107 <ng-container i18n>History</ng-container> 115 <ng-container i18n>History</ng-container>
108 </a> 116 </a>
109 117
110 </div> 118 </div>
111 119
112 <div class="panel-block"> 120 <div class="on-instance">
113 <div i18n class="block-title">VIDEOS</div> 121 <div i18n class="block-title">ON {{instanceName}}</div>
114 122
115 <a routerLink="/videos/overview" routerLinkActive="active"> 123 <a routerLink="/videos/overview" routerLinkActive="active">
116 <my-global-icon iconName="globe" aria-hidden="true"></my-global-icon> 124 <my-global-icon iconName="globe" aria-hidden="true"></my-global-icon>
@@ -134,22 +142,19 @@
134 142
135 <a routerLink="/videos/local" routerLinkActive="active"> 143 <a routerLink="/videos/local" routerLinkActive="active">
136 <my-global-icon iconName="home" aria-hidden="true"></my-global-icon> 144 <my-global-icon iconName="home" aria-hidden="true"></my-global-icon>
137 <ng-container i18n>Local</ng-container> 145 <ng-container i18n>Local videos</ng-container>
138 </a> 146 </a>
139 </div> 147 </div>
140 </div> 148 </div>
141 149
142 <div class="footer"> 150 <div class="footer">
143 <div class="panel-block"> 151 <div class="footer-block">
144 <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
145 <my-global-icon iconName="cog" aria-hidden="true"></my-global-icon>
146 <ng-container i18n>Administration</ng-container>
147 </a>
148 <a *ngIf="!isLoggedIn" (click)="openQuickSettings()"> 152 <a *ngIf="!isLoggedIn" (click)="openQuickSettings()">
149 <my-global-icon iconName="cog" aria-hidden="true"></my-global-icon> 153 <my-global-icon iconName="cog" aria-hidden="true"></my-global-icon>
150 <ng-container i18n>Settings</ng-container> 154 <ng-container i18n>Settings</ng-container>
151 </a> 155 </a>
152 <a routerLink="/about/instance"> 156
157 <a routerLink="/about" routerLinkActive="active">
153 <my-global-icon iconName="help" aria-hidden="true"></my-global-icon> 158 <my-global-icon iconName="help" aria-hidden="true"></my-global-icon>
154 <ng-container i18n>About</ng-container> 159 <ng-container i18n>About</ng-container>
155 </a> 160 </a>
@@ -168,7 +173,7 @@
168 <a i18n href="https://joinpeertube.org/faq" i18n-title title="Frequently asked questions about PeerTube" target="_blank" rel="noopener noreferrer">FAQ</a> 173 <a i18n href="https://joinpeertube.org/faq" i18n-title title="Frequently asked questions about PeerTube" target="_blank" rel="noopener noreferrer">FAQ</a>
169 <a i18n routerLink="/about/instance" fragment="statistics">Stats</a> 174 <a i18n routerLink="/about/instance" fragment="statistics">Stats</a>
170 <a i18n href="https://docs.joinpeertube.org/api-rest-reference.html" i18n-title title="API documentation" target="_blank" rel="noopener noreferrer">API</a> 175 <a i18n href="https://docs.joinpeertube.org/api-rest-reference.html" i18n-title title="API documentation" target="_blank" rel="noopener noreferrer">API</a>
171 <a (click)="openHotkeysCheatSheet()" class="c-hand" i18n>Shortcuts</a> 176 <a (click)="openHotkeysCheatSheet()" class="c-hand" i18n>Keyboard shortcuts</a>
172 </div> 177 </div>
173 </div> 178 </div>
174 179
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index 975604055..a95a80af6 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -1,6 +1,39 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4$menu-link-icon-size: 22px;
5$menu-link-icon-margin-right: 18px;
6
7@mixin menu-link {
8 display: flex;
9 align-items: center;
10 padding-left: $menu-lateral-padding;
11 color: pvar(--menuForegroundColor);
12 cursor: pointer;
13 font-size: 16px;
14 white-space: normal;
15 word-break: break-word;
16 padding-right: 20px;
17 transition: background-color .1s ease-in-out;
18
19 &.active {
20 background-color: rgba(255, 255, 255, 0.15);
21 }
22
23 &:hover, &.focus-visible {
24 background-color: rgba(255, 255, 255, 0.10);
25 }
26
27 my-global-icon {
28 @include apply-svg-color(#808080);
29
30 display: flex;
31 width: $menu-link-icon-size;
32 height: $menu-link-icon-size;
33 margin-right: $menu-link-icon-margin-right;
34 }
35}
36
4.menu-wrapper { 37.menu-wrapper {
5 position: fixed; 38 position: fixed;
6 height: calc(100vh - #{$header-height}); 39 height: calc(100vh - #{$header-height});
@@ -14,14 +47,14 @@ menu {
14 @include ellipsis; 47 @include ellipsis;
15 48
16 background-color: pvar(--menuBackgroundColor); 49 background-color: pvar(--menuBackgroundColor);
17 margin: 0;
18 padding: 0;
19 height: 100%;
20 overflow-x: hidden;
21 color: pvar(--menuForegroundColor); 50 color: pvar(--menuForegroundColor);
51
22 display: flex; 52 display: flex;
23 flex-direction: column; 53 flex-direction: column;
54 height: 100%;
24 width: 100%; 55 width: 100%;
56 margin: 0;
57 padding: 0;
25 58
26 &:focus, &:hover { 59 &:focus, &:hover {
27 overflow-y: auto; 60 overflow-y: auto;
@@ -31,7 +64,7 @@ menu {
31 overflow-y: auto; 64 overflow-y: auto;
32 } 65 }
33 66
34 &.logged-in { 67 &.is-logged-in {
35 .panel-block { 68 .panel-block {
36 margin-bottom: 20px; 69 margin-bottom: 20px;
37 } 70 }
@@ -40,19 +73,22 @@ menu {
40 margin-bottom: 15px; 73 margin-bottom: 15px;
41 } 74 }
42 } 75 }
76}
43 77
44 .top-menu { 78.top-menu {
45 flex-grow: 1; 79 flex-grow: 1;
46 width: $menu-width; 80 width: $menu-width;
47 } 81}
48 82
49 .logged-in-block { 83.logged-in-block {
50 height: 100px; 84 margin-bottom: 20px;
51 background-color: rgba(255, 255, 255, 0.15); 85 background-color: rgba(255, 255, 255, 0.15);
86
87 > div:first-child {
88 height: 80px;
52 display: flex; 89 display: flex;
53 align-items: center; 90 align-items: center;
54 justify-content: center; 91 justify-content: center;
55 margin-bottom: 20px;
56 92
57 .logged-in-info { 93 .logged-in-info {
58 @include ellipsis; 94 @include ellipsis;
@@ -95,32 +131,88 @@ menu {
95 } 131 }
96 } 132 }
97 133
98 .button-block { 134 .logged-in-menu {
99 margin: 30px 25px 35px 25px; 135 display: flex;
136 flex-direction: column;
137 align-items: flex-start;
138 border-top: 1px solid var(--greyForegroundColor);
139
140 a {
141 @include menu-link;
142 @include disable-default-a-behaviour;
100 143
101 .login-button { 144 $icon-size: 13px;
102 @include peertube-button-link; 145 $additional-margin: ($menu-link-icon-size - $icon-size) / 2;
103 @include orange-button;
104 146
105 display: block; 147 font-size: 14px;
106 width: 100%; 148 width: 100%;
107 margin-bottom: 10px; 149 min-height: 35px;
108 }
109 150
110 .create-account-button { 151 my-global-icon {
111 @include peertube-button-link; 152 width: $icon-size;
153 height: $icon-size;
112 154
113 display: block; 155 // Keep aligned with other icons
114 width: 100%; 156 margin-left: $additional-margin;
157
158 &[iconName="channel"] {
159 margin-top: -2px;
160 }
161 }
162
163 &.active,
164 &:hover,
165 &:focus-visible {
166 my-global-icon {
167 @include apply-svg-color(var(--mainBackgroundColor));
168 }
169 }
170
171 &.active {
172 $border-left-width: 4px;
115 173
116 color: #fff; 174 font-weight: $font-semibold;
117 background-color: rgba(255, 255, 255, 0.25); 175 border-left: $border-left-width solid var(--mainColor);
118 176
119 &:hover { 177 my-global-icon {
120 background-color: rgba(255, 255, 255, 0.28); 178 margin-left: $additional-margin - $border-left-width;
179 }
121 } 180 }
122 } 181 }
123 } 182 }
183}
184
185.login-buttons-block {
186 margin: 30px 25px 35px 25px;
187
188 .login-button {
189 @include peertube-button-link;
190 @include orange-button;
191
192 display: block;
193 width: 100%;
194 margin-bottom: 10px;
195 }
196
197 .create-account-button {
198 @include peertube-button-link;
199
200 display: block;
201 width: 100%;
202
203 color: #fff;
204 background-color: rgba(255, 255, 255, 0.25);
205
206 &:hover {
207 background-color: rgba(255, 255, 255, 0.28);
208 }
209 }
210}
211
212.in-my-account,
213.on-instance,
214.footer-block {
215 margin-bottom: 15px;
124 216
125 .block-title { 217 .block-title {
126 text-transform: uppercase; 218 text-transform: uppercase;
@@ -128,116 +220,86 @@ menu {
128 font-size: 13px; 220 font-size: 13px;
129 margin-bottom: 25px; 221 margin-bottom: 25px;
130 margin-left: 26px; 222 margin-left: 26px;
131 }
132 223
133 .panel-block { 224 @include ellipsis;
134 margin-bottom: 15px;
135 225
136 a { 226 margin-right: 30px;
137 @include disable-default-a-behaviour; 227 }
138
139 display: flex;
140 align-items: center;
141 padding-left: $menu-lateral-padding;
142 color: pvar(--menuForegroundColor);
143 cursor: pointer;
144 min-height: 40px;
145 font-size: 16px;
146 transition: background-color .1s ease-in-out;
147 white-space: normal;
148 word-break: break-word;
149 padding-right: 20px;
150
151 &.active {
152 background-color: rgba(255, 255, 255, 0.15);
153 }
154
155 &:hover, &.focus-visible {
156 background-color: rgba(255, 255, 255, 0.10);
157 }
158
159 my-global-icon {
160 @include apply-svg-color(#808080);
161 228
162 display: flex; 229 a {
163 width: 22px; 230 @include menu-link;
164 height: 22px; 231 @include disable-default-a-behaviour;
165 margin-right: 18px;
166 232
167 &[iconName="playlists"] { 233 min-height: 40px;
168 height: 24px;
169 width: 24px;
170 234
171 margin-right: 16px; 235 my-global-icon {
172 } 236 &[iconName="playlists"] {
237 height: 24px;
238 width: 24px;
173 239
174 &[iconName="videos"] { 240 margin-right: 16px;
175 position: relative;
176 right: -1px;
177 }
178 } 241 }
179 242
180 .icon { 243 &[iconName="videos"] {
181 @include icon(22px); 244 position: relative;
182 245 right: -1px;
183 margin-right: 18px;
184 } 246 }
185 } 247 }
186 } 248 }
249}
250
251.footer {
252 width: $menu-width;
253 padding-bottom: 15px;
254
255 .bottom-links {
256 display: flex;
257 flex-direction: column;
258 padding: 0 $menu-lateral-padding;
259 }
187 260
188 .footer { 261 $footer-links-base-opacity: .8;
189 width: $menu-width;
190 padding-bottom: 15px;
191 262
192 .bottom-links { 263 .footer-links {
264 &, > div {
193 display: flex; 265 display: flex;
194 flex-direction: column; 266 flex-wrap: wrap;
195 padding: 0 $menu-lateral-padding;
196 } 267 }
197 268
198 $footer-links-base-opacity: .8; 269 a, span[role=button] {
270 display: inline-block;
271 text-decoration: none;
272 color: pvar(--mainBackgroundColor);
273 opacity: $footer-links-base-opacity;
274 white-space: nowrap;
275 font-size: 90%;
276 font-weight: 500;
277 line-height: 1.4rem;
278 margin-right: 8px;
279
280 &.inline-global-icon {
281 display: inline-flex;
282 align-items: center;
283 white-space: nowrap;
284 height: 1.4rem;
199 285
200 .footer-links { 286 my-global-icon {
201 &, > div { 287 @include apply-svg-color(pvar(--mainBackgroundColor));
202 display: flex;
203 flex-wrap: wrap;
204 }
205 288
206 a, span[role=button] { 289 display: flex;
207 display: inline-block; 290 width: auto;
208 text-decoration: none; 291 height: 90%;
209 color: pvar(--mainBackgroundColor); 292 margin-right: .2rem;
210 opacity: $footer-links-base-opacity;
211 white-space: nowrap;
212 font-size: 90%;
213 font-weight: 500;
214 line-height: 1.4rem;
215 margin-right: 8px;
216
217 &.inline-global-icon {
218 display: inline-flex;
219 align-items: center;
220 white-space: nowrap;
221 height: 1.4rem;
222
223 my-global-icon {
224 @include apply-svg-color(pvar(--mainBackgroundColor));
225
226 display: flex;
227 width: auto;
228 height: 90%;
229 margin-right: .2rem;
230 }
231 } 293 }
232 } 294 }
233 } 295 }
296 }
234 297
235 .footer-copyleft small a { 298 .footer-copyleft small a {
236 @include disable-default-a-behaviour; 299 @include disable-default-a-behaviour;
237 300
238 color: pvar(--mainBackgroundColor); 301 color: pvar(--mainBackgroundColor);
239 opacity: $footer-links-base-opacity - .2; 302 opacity: $footer-links-base-opacity - .2;
240 }
241 } 303 }
242} 304}
243 305
@@ -292,7 +354,7 @@ menu {
292 354
293.icon { 355.icon {
294 @include disable-outline; 356 @include disable-outline;
295 @include icon(22px); 357 @include icon($menu-link-icon-size);
296 opacity: 0.8; 358 opacity: 0.8;
297 359
298 &.icon-shortcuts { 360 &.icon-shortcuts {
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts
index f9a0a9f57..48ed91973 100644
--- a/client/src/app/menu/menu.component.ts
+++ b/client/src/app/menu/menu.component.ts
@@ -61,6 +61,29 @@ export class MenuComponent implements OnInit {
61 } 61 }
62 } 62 }
63 63
64 get language () {
65 return this.languageChooserModal.getCurrentLanguage()
66 }
67
68 get nsfwPolicy () {
69 if (!this.user) return
70
71 switch (this.user.nsfwPolicy) {
72 case 'do_not_list':
73 return $localize`hide`
74
75 case 'blur':
76 return $localize`blur`
77
78 case 'display':
79 return $localize`display`
80 }
81 }
82
83 get instanceName () {
84 return this.serverConfig.instance.name
85 }
86
64 ngOnInit () { 87 ngOnInit () {
65 this.serverConfig = this.serverService.getTmpConfig() 88 this.serverConfig = this.serverService.getTmpConfig()
66 this.serverService.getConfig() 89 this.serverService.getConfig()
@@ -109,25 +132,6 @@ export class MenuComponent implements OnInit {
109 }) 132 })
110 } 133 }
111 134
112 get language () {
113 return this.languageChooserModal.getCurrentLanguage()
114 }
115
116 get nsfwPolicy () {
117 if (!this.user) return
118
119 switch (this.user.nsfwPolicy) {
120 case 'do_not_list':
121 return $localize`hide`
122
123 case 'blur':
124 return $localize`blur`
125
126 case 'display':
127 return $localize`display`
128 }
129 }
130
131 isRegistrationAllowed () { 135 isRegistrationAllowed () {
132 return this.serverConfig.signup.allowed && 136 return this.serverConfig.signup.allowed &&
133 this.serverConfig.signup.allowedForCurrentIP 137 this.serverConfig.signup.allowedForCurrentIP
diff --git a/client/src/app/shared/shared-main/users/user-notification.model.ts b/client/src/app/shared/shared-main/users/user-notification.model.ts
index a068daaac..648bb7fe0 100644
--- a/client/src/app/shared/shared-main/users/user-notification.model.ts
+++ b/client/src/app/shared/shared-main/users/user-notification.model.ts
@@ -211,7 +211,7 @@ export class UserNotification implements UserNotificationServer {
211 } 211 }
212 212
213 private buildVideoImportUrl () { 213 private buildVideoImportUrl () {
214 return '/my-account/video-imports' 214 return '/my-library/video-imports'
215 } 215 }
216 216
217 private buildVideoImportIdentifier (videoImport: { targetUrl?: string, magnetUri?: string, torrentName?: string }) { 217 private buildVideoImportIdentifier (videoImport: { targetUrl?: string, magnetUri?: string, torrentName?: string }) {
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html
index 87ab68b87..aa117dcc6 100644
--- a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html
+++ b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.html
@@ -36,7 +36,7 @@
36 </div> 36 </div>
37 </a> 37 </a>
38 38
39 <my-edit-button *ngIf="owned && touchScreenEditButton" [routerLink]="[ '/my-account', 'video-playlists', playlist.uuid ]"></my-edit-button> 39 <my-edit-button *ngIf="owned && touchScreenEditButton" [routerLink]="[ '/my-library', 'video-playlists', playlist.uuid ]"></my-edit-button>
40 40
41 <div *ngIf="owned" class="more" ngbDropdown #moreDropdown="ngbDropdown" placement="left auto" 41 <div *ngIf="owned" class="more" ngbDropdown #moreDropdown="ngbDropdown" placement="left auto"
42 (openChange)="onDropdownOpenChange()" autoClose="outside" 42 (openChange)="onDropdownOpenChange()" autoClose="outside"
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.ts b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.ts
index 4b0669a32..251aa868a 100644
--- a/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.ts
+++ b/client/src/app/shared/shared-video-playlist/video-playlist-miniature.component.ts
@@ -14,7 +14,7 @@ export class VideoPlaylistMiniatureComponent {
14 @Input() displayPrivacy = false 14 @Input() displayPrivacy = false
15 15
16 getPlaylistUrl () { 16 getPlaylistUrl () {
17 if (this.toManage) return [ '/my-account/video-playlists', this.playlist.uuid ] 17 if (this.toManage) return [ '/my-library/video-playlists', this.playlist.uuid ]
18 if (this.playlist.videosLength === 0) return null 18 if (this.playlist.videosLength === 0) return null
19 19
20 return [ '/videos/watch/playlist', this.playlist.uuid ] 20 return [ '/videos/watch/playlist', this.playlist.uuid ]