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.component.ts27
-rw-r--r--client/src/app/menu/menu.component.html58
-rw-r--r--client/src/app/menu/menu.component.scss86
-rw-r--r--client/src/app/shared/images/global-icon.component.ts17
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.html6
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.scss9
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.ts10
7 files changed, 138 insertions, 75 deletions
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts
index f624ff505..d98d06f8e 100644
--- a/client/src/app/+my-account/my-account.component.ts
+++ b/client/src/app/+my-account/my-account.component.ts
@@ -21,23 +21,28 @@ export class MyAccountComponent {
21 children: [ 21 children: [
22 { 22 {
23 label: this.i18n('My channels'), 23 label: this.i18n('My channels'),
24 routerLink: '/my-account/video-channels' 24 routerLink: '/my-account/video-channels',
25 iconName: 'folder'
25 }, 26 },
26 { 27 {
27 label: this.i18n('My videos'), 28 label: this.i18n('My videos'),
28 routerLink: '/my-account/videos' 29 routerLink: '/my-account/videos',
30 iconName: 'videos'
29 }, 31 },
30 { 32 {
31 label: this.i18n('My playlists'), 33 label: this.i18n('My playlists'),
32 routerLink: '/my-account/video-playlists' 34 routerLink: '/my-account/video-playlists',
35 iconName: 'playlists'
33 }, 36 },
34 { 37 {
35 label: this.i18n('My subscriptions'), 38 label: this.i18n('My subscriptions'),
36 routerLink: '/my-account/subscriptions' 39 routerLink: '/my-account/subscriptions',
40 iconName: 'subscriptions'
37 }, 41 },
38 { 42 {
39 label: this.i18n('My history'), 43 label: this.i18n('My history'),
40 routerLink: '/my-account/history/videos' 44 routerLink: '/my-account/history/videos',
45 iconName: 'history'
41 } 46 }
42 ] 47 ]
43 } 48 }
@@ -45,7 +50,8 @@ export class MyAccountComponent {
45 if (this.isVideoImportEnabled()) { 50 if (this.isVideoImportEnabled()) {
46 libraryEntries.children.push({ 51 libraryEntries.children.push({
47 label: 'My imports', 52 label: 'My imports',
48 routerLink: '/my-account/video-imports' 53 routerLink: '/my-account/video-imports',
54 iconName: 'cloud-download'
49 }) 55 })
50 } 56 }
51 57
@@ -54,15 +60,18 @@ export class MyAccountComponent {
54 children: [ 60 children: [
55 { 61 {
56 label: this.i18n('Muted accounts'), 62 label: this.i18n('Muted accounts'),
57 routerLink: '/my-account/blocklist/accounts' 63 routerLink: '/my-account/blocklist/accounts',
64 iconName: 'user'
58 }, 65 },
59 { 66 {
60 label: this.i18n('Muted instances'), 67 label: this.i18n('Muted instances'),
61 routerLink: '/my-account/blocklist/servers' 68 routerLink: '/my-account/blocklist/servers',
69 iconName: 'server'
62 }, 70 },
63 { 71 {
64 label: this.i18n('Ownership changes'), 72 label: this.i18n('Ownership changes'),
65 routerLink: '/my-account/ownership' 73 routerLink: '/my-account/ownership',
74 iconName: 'im-with-her'
66 } 75 }
67 ] 76 ]
68 } 77 }
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html
index 5622b3a31..e80e6b803 100644
--- a/client/src/app/menu/menu.component.html
+++ b/client/src/app/menu/menu.component.html
@@ -1,5 +1,5 @@
1<div class="menu-wrapper"> 1<div class="menu-wrapper">
2 <menu> 2 <menu [ngClass]="{ '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"></my-avatar-notification> 5 <my-avatar-notification [user]="user"></my-avatar-notification>
@@ -13,20 +13,16 @@
13 <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon> 13 <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon>
14 14
15 <div ngbDropdownMenu> 15 <div ngbDropdownMenu>
16 <a *ngIf="user.account" i18n [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="dropdown-item"> 16 <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="dropdown-item">
17 My public profile 17 <my-global-icon iconName="go"></my-global-icon> <ng-container i18n>My public profile</ng-container>
18 </a> 18 </a>
19 19
20 <a i18n routerLink="/my-account" class="dropdown-item"> 20 <a routerLink="/my-account" class="dropdown-item">
21 My account 21 <my-global-icon iconName="user"></my-global-icon> <ng-container i18n>My account</ng-container>
22 </a> 22 </a>
23 23
24 <a i18n routerLink="/my-account/videos" class="dropdown-item"> 24 <a (click)="logout($event)" class="dropdown-item" href="#">
25 My videos 25 <my-global-icon iconName="sign-out"></my-global-icon> <ng-container i18n>Log out</ng-container>
26 </a>
27
28 <a i18n (click)="logout($event)" class="dropdown-item" href="#">
29 Log out
30 </a> 26 </a>
31 </div> 27 </div>
32 </div> 28 </div>
@@ -37,31 +33,51 @@
37 <a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> 33 <a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a>
38 </div> 34 </div>
39 35
40 <div class="panel-block"> 36 <div *ngIf="isLoggedIn" class="panel-block">
41 <div i18n class="block-title">Videos</div> 37 <div i18n class="block-title">My library</div>
38
39 <a routerLink="/my-account/videos" routerLinkActive="active">
40 <my-global-icon iconName="videos"></my-global-icon>
41 <ng-container i18n>Videos</ng-container>
42 </a>
43
44 <a routerLink="/my-account/video-playlists" routerLinkActive="active">
45 <my-global-icon iconName="playlists"></my-global-icon>
46 <ng-container i18n>Playlists</ng-container>
47 </a>
42 48
43 <a *ngIf="isLoggedIn" routerLink="/videos/subscriptions" routerLinkActive="active"> 49 <a routerLink="/videos/subscriptions" routerLinkActive="active">
44 <span class="icon icon-videos-subscriptions"></span> 50 <my-global-icon iconName="subscriptions"></my-global-icon>
45 <ng-container i18n>Subscriptions</ng-container> 51 <ng-container i18n>Subscriptions</ng-container>
46 </a> 52 </a>
47 53
54 <a routerLink="/my-account/history/videos" routerLinkActive="active">
55 <my-global-icon iconName="history"></my-global-icon>
56 <ng-container i18n>History</ng-container>
57 </a>
58
59 </div>
60
61 <div class="panel-block">
62 <div i18n class="block-title">Videos</div>
63
48 <a routerLink="/videos/overview" routerLinkActive="active"> 64 <a routerLink="/videos/overview" routerLinkActive="active">
49 <span class="icon icon-videos-overview"></span> 65 <my-global-icon iconName="globe"></my-global-icon>
50 <ng-container i18n>Overview</ng-container> 66 <ng-container i18n>Overview</ng-container>
51 </a> 67 </a>
52 68
53 <a routerLink="/videos/trending" routerLinkActive="active"> 69 <a routerLink="/videos/trending" routerLinkActive="active">
54 <span class="icon icon-videos-trending"></span> 70 <my-global-icon iconName="trending"></my-global-icon>
55 <ng-container i18n>Trending</ng-container> 71 <ng-container i18n>Trending</ng-container>
56 </a> 72 </a>
57 73
58 <a routerLink="/videos/recently-added" routerLinkActive="active"> 74 <a routerLink="/videos/recently-added" routerLinkActive="active">
59 <span class="icon icon-videos-recently-added"></span> 75 <my-global-icon iconName="recently-added"></my-global-icon>
60 <ng-container i18n>Recently added</ng-container> 76 <ng-container i18n>Recently added</ng-container>
61 </a> 77 </a>
62 78
63 <a routerLink="/videos/local" routerLinkActive="active"> 79 <a routerLink="/videos/local" routerLinkActive="active">
64 <span class="icon icon-videos-local"></span> 80 <my-global-icon iconName="home"></my-global-icon>
65 <ng-container i18n>Local</ng-container> 81 <ng-container i18n>Local</ng-container>
66 </a> 82 </a>
67 </div> 83 </div>
@@ -70,12 +86,12 @@
70 <div class="block-title" i18n>More</div> 86 <div class="block-title" i18n>More</div>
71 87
72 <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> 88 <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
73 <span class="icon icon-administration"></span> 89 <my-global-icon iconName="administration"></my-global-icon>
74 <ng-container i18n>Administration</ng-container> 90 <ng-container i18n>Administration</ng-container>
75 </a> 91 </a>
76 92
77 <a routerLink="/about" routerLinkActive="active"> 93 <a routerLink="/about" routerLinkActive="active">
78 <span class="icon icon-about"></span> 94 <my-global-icon iconName="about"></my-global-icon>
79 <ng-container i18n>About</ng-container> 95 <ng-container i18n>About</ng-container>
80 </a> 96 </a>
81 </div> 97 </div>
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index 7b392b599..9241e8059 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -26,6 +26,16 @@ menu {
26 overflow-y: auto; 26 overflow-y: auto;
27 } 27 }
28 28
29 &.logged-in {
30 .panel-block {
31 margin-bottom: 25px;
32 }
33
34 .block-title {
35 margin-bottom: 15px;
36 }
37 }
38
29 .top-menu { 39 .top-menu {
30 flex-grow: 1; 40 flex-grow: 1;
31 width: $menu-width; 41 width: $menu-width;
@@ -37,7 +47,7 @@ menu {
37 display: flex; 47 display: flex;
38 align-items: center; 48 align-items: center;
39 justify-content: center; 49 justify-content: center;
40 margin-bottom: 35px; 50 margin-bottom: 20px;
41 51
42 .logged-in-info { 52 .logged-in-info {
43 @include ellipsis; 53 @include ellipsis;
@@ -74,6 +84,24 @@ menu {
74 border: none; 84 border: none;
75 } 85 }
76 } 86 }
87
88 .dropdown-item {
89 @include dropdown-with-icon-item;
90
91 my-global-icon {
92 @include apply-svg-color(var(--mainForegroundColor));
93
94 width: 22px;
95 height: 22px;
96
97 &[iconName="sign-out"] {
98 position: relative;
99 right: -1px;
100 height: 21px;
101 width: 21px;
102 }
103 }
104 }
77 } 105 }
78 } 106 }
79 107
@@ -134,57 +162,31 @@ menu {
134 background-color: rgba(255, 255, 255, 0.10); 162 background-color: rgba(255, 255, 255, 0.10);
135 } 163 }
136 164
137 .icon { 165 my-global-icon {
138 @include icon(22px); 166 @include apply-svg-color(#808080);
139 167
168 display: flex;
169 width: 22px;
170 height: 22px;
140 margin-right: 18px; 171 margin-right: 18px;
141 172
142 &.icon-videos-subscriptions { 173 &[iconName="playlists"] {
143 position: relative; 174 height: 24px;
144 top: -1px; 175 width: 24px;
145 background-image: url('../../assets/images/menu/subscriptions.svg');
146 }
147
148 &.icon-videos-overview {
149 position: relative;
150 background-image: url('../../assets/images/menu/globe.svg');
151 }
152
153 &.icon-videos-trending {
154 position: relative;
155 top: -1px;
156 background-image: url('../../assets/images/menu/trending.svg');
157 }
158 176
159 &.icon-videos-recently-added { 177 margin-right: 16px;
160 width: 23px;
161 height: 23px;
162 background-image: url('../../assets/images/menu/recently-added.svg');
163 } 178 }
164 179
165 &.icon-videos-local { 180 &[iconName="videos"] {
166 width: 23px;
167 height: 23px;
168
169 position: relative; 181 position: relative;
170 top: -1px; 182 right: -1px;
171
172 background-image: url('../../assets/images/menu/home.svg');
173 }
174
175 &.icon-administration {
176 width: 23px;
177 height: 23px;
178
179 background-image: url('../../assets/images/menu/administration.svg');
180 } 183 }
184 }
181 185
182 &.icon-about { 186 .icon {
183 width: 23px; 187 @include icon(22px);
184 height: 23px;
185 188
186 background-image: url('../../assets/images/menu/about.svg'); 189 margin-right: 18px;
187 }
188 } 190 }
189 } 191 }
190 } 192 }
diff --git a/client/src/app/shared/images/global-icon.component.ts b/client/src/app/shared/images/global-icon.component.ts
index 3fa6fea96..d85f269ea 100644
--- a/client/src/app/shared/images/global-icon.component.ts
+++ b/client/src/app/shared/images/global-icon.component.ts
@@ -2,6 +2,8 @@ import { Component, ElementRef, Input, OnInit } from '@angular/core'
2 2
3const icons = { 3const icons = {
4 'add': require('../../../assets/images/global/add.html'), 4 'add': require('../../../assets/images/global/add.html'),
5 'user': require('../../../assets/images/global/user.html'),
6 'sign-out': require('../../../assets/images/global/sign-out.html'),
5 'syndication': require('../../../assets/images/global/syndication.html'), 7 'syndication': require('../../../assets/images/global/syndication.html'),
6 'help': require('../../../assets/images/global/help.html'), 8 'help': require('../../../assets/images/global/help.html'),
7 'sparkle': require('../../../assets/images/global/sparkle.html'), 9 'sparkle': require('../../../assets/images/global/sparkle.html'),
@@ -11,12 +13,15 @@ const icons = {
11 'no': require('../../../assets/images/global/no.html'), 13 'no': require('../../../assets/images/global/no.html'),
12 'cloud-download': require('../../../assets/images/global/cloud-download.html'), 14 'cloud-download': require('../../../assets/images/global/cloud-download.html'),
13 'undo': require('../../../assets/images/global/undo.html'), 15 'undo': require('../../../assets/images/global/undo.html'),
16 'history': require('../../../assets/images/global/history.html'),
14 'circle-tick': require('../../../assets/images/global/circle-tick.html'), 17 'circle-tick': require('../../../assets/images/global/circle-tick.html'),
15 'cog': require('../../../assets/images/global/cog.html'), 18 'cog': require('../../../assets/images/global/cog.html'),
16 'download': require('../../../assets/images/global/download.html'), 19 'download': require('../../../assets/images/global/download.html'),
20 'go': require('../../../assets/images/menu/go.html'),
17 'edit': require('../../../assets/images/global/edit.html'), 21 'edit': require('../../../assets/images/global/edit.html'),
18 'im-with-her': require('../../../assets/images/global/im-with-her.html'), 22 'im-with-her': require('../../../assets/images/global/im-with-her.html'),
19 'delete': require('../../../assets/images/global/delete.html'), 23 'delete': require('../../../assets/images/global/delete.html'),
24 'server': require('../../../assets/images/global/server.html'),
20 'cross': require('../../../assets/images/global/cross.html'), 25 'cross': require('../../../assets/images/global/cross.html'),
21 'validate': require('../../../assets/images/global/validate.html'), 26 'validate': require('../../../assets/images/global/validate.html'),
22 'tick': require('../../../assets/images/global/tick.html'), 27 'tick': require('../../../assets/images/global/tick.html'),
@@ -28,7 +33,17 @@ const icons = {
28 'share': require('../../../assets/images/video/share.html'), 33 'share': require('../../../assets/images/video/share.html'),
29 'upload': require('../../../assets/images/video/upload.html'), 34 'upload': require('../../../assets/images/video/upload.html'),
30 'playlist-add': require('../../../assets/images/video/playlist-add.html'), 35 'playlist-add': require('../../../assets/images/video/playlist-add.html'),
31 'play': require('../../../assets/images/global/play.html') 36 'play': require('../../../assets/images/global/play.html'),
37 'playlists': require('../../../assets/images/global/playlists.html'),
38 'about': require('../../../assets/images/menu/about.html'),
39 'globe': require('../../../assets/images/menu/globe.html'),
40 'home': require('../../../assets/images/menu/home.html'),
41 'recently-added': require('../../../assets/images/menu/recently-added.html'),
42 'trending': require('../../../assets/images/menu/trending.html'),
43 'videos': require('../../../assets/images/global/videos.html'),
44 'folder': require('../../../assets/images/global/folder.html'),
45 'administration': require('../../../assets/images/menu/administration.html'),
46 'subscriptions': require('../../../assets/images/menu/subscriptions.html')
32} 47}
33 48
34export type GlobalIconName = keyof typeof icons 49export type GlobalIconName = keyof typeof icons
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.html b/client/src/app/shared/menu/top-menu-dropdown.component.html
index d3c896019..8d58fa1db 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.html
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.html
@@ -13,7 +13,11 @@
13 </span> 13 </span>
14 14
15 <div ngbDropdownMenu> 15 <div ngbDropdownMenu>
16 <a *ngFor="let menuChild of menuEntry.children" class="dropdown-item" [routerLink]="menuChild.routerLink">{{ menuChild.label }}</a> 16 <a *ngFor="let menuChild of menuEntry.children" class="dropdown-item" [ngClass]="{ icon: hasIcons }" [routerLink]="menuChild.routerLink">
17 <my-global-icon *ngIf="menuChild.iconName" [iconName]="menuChild.iconName"></my-global-icon>
18
19 {{ menuChild.label }}
20 </a>
17 </div> 21 </div>
18 </div> 22 </div>
19 23
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.scss b/client/src/app/shared/menu/top-menu-dropdown.component.scss
index 77159532f..d7c7de957 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.scss
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.scss
@@ -1,3 +1,6 @@
1@import '_variables';
2@import '_mixins';
3
1.parent-entry { 4.parent-entry {
2 span[role=button] { 5 span[role=button] {
3 cursor: pointer; 6 cursor: pointer;
@@ -16,3 +19,9 @@
16/deep/ .dropdown-menu { 19/deep/ .dropdown-menu {
17 margin-top: 0 !important; 20 margin-top: 0 !important;
18} 21}
22
23.icon {
24 @include dropdown-with-icon-item;
25
26 top: -1px;
27}
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.ts b/client/src/app/shared/menu/top-menu-dropdown.component.ts
index e859c30dd..e951ea236 100644
--- a/client/src/app/shared/menu/top-menu-dropdown.component.ts
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.ts
@@ -3,6 +3,7 @@ import { filter, take } from 'rxjs/operators'
3import { NavigationEnd, Router } from '@angular/router' 3import { NavigationEnd, Router } from '@angular/router'
4import { Subscription } from 'rxjs' 4import { Subscription } from 'rxjs'
5import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' 5import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
6import { GlobalIconName } from '@app/shared/images/global-icon.component'
6 7
7export type TopMenuDropdownParam = { 8export type TopMenuDropdownParam = {
8 label: string 9 label: string
@@ -11,6 +12,8 @@ export type TopMenuDropdownParam = {
11 children?: { 12 children?: {
12 label: string 13 label: string
13 routerLink: string 14 routerLink: string
15
16 iconName?: GlobalIconName
14 }[] 17 }[]
15} 18}
16 19
@@ -23,6 +26,7 @@ export class TopMenuDropdownComponent implements OnInit, OnDestroy {
23 @Input() menuEntries: TopMenuDropdownParam[] = [] 26 @Input() menuEntries: TopMenuDropdownParam[] = []
24 27
25 suffixLabels: { [ parentLabel: string ]: string } 28 suffixLabels: { [ parentLabel: string ]: string }
29 hasIcons = false
26 30
27 private openedOnHover = false 31 private openedOnHover = false
28 private routeSub: Subscription 32 private routeSub: Subscription
@@ -35,6 +39,10 @@ export class TopMenuDropdownComponent implements OnInit, OnDestroy {
35 this.routeSub = this.router.events 39 this.routeSub = this.router.events
36 .pipe(filter(event => event instanceof NavigationEnd)) 40 .pipe(filter(event => event instanceof NavigationEnd))
37 .subscribe(() => this.updateChildLabels(window.location.pathname)) 41 .subscribe(() => this.updateChildLabels(window.location.pathname))
42
43 this.hasIcons = this.menuEntries.some(
44 e => e.children && e.children.some(c => !!c.iconName)
45 )
38 } 46 }
39 47
40 ngOnDestroy () { 48 ngOnDestroy () {
@@ -48,7 +56,7 @@ export class TopMenuDropdownComponent implements OnInit, OnDestroy {
48 // Menu was closed 56 // Menu was closed
49 dropdown.openChange 57 dropdown.openChange
50 .pipe(take(1)) 58 .pipe(take(1))
51 .subscribe(e => this.openedOnHover = false) 59 .subscribe(() => this.openedOnHover = false)
52 } 60 }
53 61
54 dropdownAnchorClicked (dropdown: NgbDropdown) { 62 dropdownAnchorClicked (dropdown: NgbDropdown) {