diff options
Diffstat (limited to 'client/src/app/menu')
-rw-r--r-- | client/src/app/menu/index.ts | 1 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.html | 50 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.scss | 193 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.ts | 101 |
4 files changed, 345 insertions, 0 deletions
diff --git a/client/src/app/menu/index.ts b/client/src/app/menu/index.ts new file mode 100644 index 000000000..421271c12 --- /dev/null +++ b/client/src/app/menu/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './menu.component' | |||
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html new file mode 100644 index 000000000..7a80fa4de --- /dev/null +++ b/client/src/app/menu/menu.component.html | |||
@@ -0,0 +1,50 @@ | |||
1 | <menu> | ||
2 | <div *ngIf="isLoggedIn" class="logged-in-block"> | ||
3 | <img [src]="getUserAvatarPath()" alt="Avatar" /> | ||
4 | |||
5 | <div class="logged-in-info"> | ||
6 | <a routerLink="/account/settings" class="logged-in-username">{{ user.username }}</a> | ||
7 | <div class="logged-in-email">{{ user.email }}</div> | ||
8 | </div> | ||
9 | |||
10 | <div class="logged-in-more" dropdown placement="right" container="body"> | ||
11 | <span class="glyphicon glyphicon-option-vertical" dropdownToggle></span> | ||
12 | |||
13 | <ul *dropdownMenu class="dropdown-menu"> | ||
14 | <li> | ||
15 | <a (click)="logout($event)" class="dropdown-item" title="Log out" href="#"> | ||
16 | Log out | ||
17 | </a> | ||
18 | </li> | ||
19 | </ul> | ||
20 | </div> | ||
21 | </div> | ||
22 | |||
23 | <div *ngIf="!isLoggedIn" class="button-block"> | ||
24 | <a routerLink="/login" class="login-button">Login</a> | ||
25 | <a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> | ||
26 | </div> | ||
27 | |||
28 | <div class="panel-block"> | ||
29 | <div class="block-title">Videos</div> | ||
30 | |||
31 | <a routerLink="/videos/trending" routerLinkActive="active"> | ||
32 | <span class="icon icon-videos-trending"></span> | ||
33 | Trending | ||
34 | </a> | ||
35 | |||
36 | <a routerLink="/videos/recently-added" routerLinkActive="active"> | ||
37 | <span class="icon icon-videos-recently-added"></span> | ||
38 | Recently added | ||
39 | </a> | ||
40 | </div> | ||
41 | |||
42 | <div *ngIf="userHasAdminAccess" class="panel-block"> | ||
43 | <div class="block-title">More</div> | ||
44 | |||
45 | <a [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> | ||
46 | <span class="icon icon-administration"></span> | ||
47 | Administration | ||
48 | </a> | ||
49 | </div> | ||
50 | </menu> | ||
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss new file mode 100644 index 000000000..97ceadde3 --- /dev/null +++ b/client/src/app/menu/menu.component.scss | |||
@@ -0,0 +1,193 @@ | |||
1 | menu { | ||
2 | background-color: $black-background; | ||
3 | margin: 0; | ||
4 | padding: 0; | ||
5 | height: 100%; | ||
6 | white-space: nowrap; | ||
7 | text-overflow: ellipsis; | ||
8 | overflow: hidden; | ||
9 | z-index: 1000; | ||
10 | color: $menu-color; | ||
11 | |||
12 | .logged-in-block { | ||
13 | height: 100px; | ||
14 | background-color: rgba(255, 255, 255, 0.15); | ||
15 | display: flex; | ||
16 | align-items: center; | ||
17 | justify-content: center; | ||
18 | margin-bottom: 35px; | ||
19 | |||
20 | img { | ||
21 | margin-left: 20px; | ||
22 | margin-right: 10px; | ||
23 | |||
24 | @include avatar(34px); | ||
25 | } | ||
26 | |||
27 | .logged-in-info { | ||
28 | flex-grow: 1; | ||
29 | |||
30 | .logged-in-username { | ||
31 | font-size: 16px; | ||
32 | font-weight: $font-semibold; | ||
33 | color: $menu-color; | ||
34 | cursor: pointer; | ||
35 | |||
36 | @include disable-default-a-behaviour; | ||
37 | } | ||
38 | |||
39 | .logged-in-email { | ||
40 | font-size: 13px; | ||
41 | color: #C6C6C6; | ||
42 | white-space: nowrap; | ||
43 | overflow: hidden; | ||
44 | text-overflow: ellipsis; | ||
45 | max-width: 140px; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | .logged-in-more { | ||
50 | margin-right: 20px; | ||
51 | |||
52 | .glyphicon { | ||
53 | cursor: pointer; | ||
54 | font-size: 18px; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | .button-block { | ||
60 | margin: 30px 25px 35px 25px; | ||
61 | |||
62 | .login-button, .create-account-button { | ||
63 | font-weight: $font-semibold; | ||
64 | font-size: 15px; | ||
65 | height: $button-height; | ||
66 | line-height: $button-height; | ||
67 | width: 100%; | ||
68 | border-radius: 3px; | ||
69 | text-align: center; | ||
70 | color: $menu-color; | ||
71 | display: block; | ||
72 | cursor: pointer; | ||
73 | margin-bottom: 15px; | ||
74 | |||
75 | @include disable-default-a-behaviour; | ||
76 | |||
77 | &.login-button { | ||
78 | background-color: $orange-color; | ||
79 | margin-bottom: 10px; | ||
80 | } | ||
81 | |||
82 | &.create-account-button { | ||
83 | background-color: rgba(255, 255, 255, 0.25); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | .block-title { | ||
89 | text-transform: uppercase; | ||
90 | font-weight: $font-bold; // Bold | ||
91 | font-size: 13px; | ||
92 | margin-bottom: 25px; | ||
93 | } | ||
94 | |||
95 | .panel-block { | ||
96 | margin-bottom: 45px; | ||
97 | margin-left: 26px; | ||
98 | |||
99 | a { | ||
100 | display: flex; | ||
101 | color: $menu-color; | ||
102 | cursor: pointer; | ||
103 | height: 22px; | ||
104 | line-height: 22px; | ||
105 | font-size: 16px; | ||
106 | margin-bottom: 15px; | ||
107 | @include disable-default-a-behaviour; | ||
108 | |||
109 | .icon { | ||
110 | @include icon(22px); | ||
111 | |||
112 | margin-right: 18px; | ||
113 | |||
114 | &.icon-videos-trending { | ||
115 | position: relative; | ||
116 | top: -2px; | ||
117 | background-image: url('../../assets/images/menu/trending.svg'); | ||
118 | } | ||
119 | |||
120 | &.icon-videos-recently-added { | ||
121 | width: 23px; | ||
122 | height: 23px; | ||
123 | position: relative; | ||
124 | top: -1px; | ||
125 | background-image: url('../../assets/images/menu/recently-added.svg'); | ||
126 | } | ||
127 | |||
128 | &.icon-administration { | ||
129 | width: 23px; | ||
130 | height: 23px; | ||
131 | |||
132 | background-image: url('../../assets/images/menu/administration.svg'); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | @media screen and (max-width: 800px) { | ||
140 | menu { | ||
141 | .logged-in-block { | ||
142 | padding-left: 10px; | ||
143 | |||
144 | img { | ||
145 | display: none; | ||
146 | } | ||
147 | |||
148 | .logged-in-info { | ||
149 | .logged-in-username { | ||
150 | font-size: 14px; | ||
151 | } | ||
152 | |||
153 | .logged-in-email { | ||
154 | font-size: 11px; | ||
155 | max-width: 120px; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | .logged-in-more { | ||
160 | margin-right: 5px; | ||
161 | |||
162 | .login-button, .create-account-button { | ||
163 | font-weight: $font-semibold; | ||
164 | font-size: 15px; | ||
165 | height: $button-height; | ||
166 | line-height: $button-height; | ||
167 | width: 190px; | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | .button-block { | ||
173 | margin: 20px 10px 25px 10px; | ||
174 | |||
175 | .login-button, .create-account-button { | ||
176 | font-size: 13px; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | .panel-block { | ||
181 | margin-bottom: 30px; | ||
182 | margin-left: 10px; | ||
183 | |||
184 | a { | ||
185 | font-size: 14px; | ||
186 | |||
187 | .icon { | ||
188 | margin-right: 10px; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | } | ||
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts new file mode 100644 index 000000000..8b8b714a8 --- /dev/null +++ b/client/src/app/menu/menu.component.ts | |||
@@ -0,0 +1,101 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | ||
2 | import { Router } from '@angular/router' | ||
3 | import { UserRight } from '../../../../shared/models/users/user-right.enum' | ||
4 | import { AuthService, AuthStatus, ServerService } from '../core' | ||
5 | import { User } from '../shared/users/user.model' | ||
6 | |||
7 | @Component({ | ||
8 | selector: 'my-menu', | ||
9 | templateUrl: './menu.component.html', | ||
10 | styleUrls: [ './menu.component.scss' ] | ||
11 | }) | ||
12 | export class MenuComponent implements OnInit { | ||
13 | user: User | ||
14 | isLoggedIn: boolean | ||
15 | userHasAdminAccess = false | ||
16 | |||
17 | private routesPerRight = { | ||
18 | [UserRight.MANAGE_USERS]: '/admin/users', | ||
19 | [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends', | ||
20 | [UserRight.MANAGE_VIDEO_ABUSES]: '/admin/video-abuses', | ||
21 | [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/video-blacklist' | ||
22 | } | ||
23 | |||
24 | constructor ( | ||
25 | private authService: AuthService, | ||
26 | private serverService: ServerService, | ||
27 | private router: Router | ||
28 | ) {} | ||
29 | |||
30 | ngOnInit () { | ||
31 | this.isLoggedIn = this.authService.isLoggedIn() | ||
32 | if (this.isLoggedIn === true) this.user = this.authService.getUser() | ||
33 | this.computeIsUserHasAdminAccess() | ||
34 | |||
35 | this.authService.loginChangedSource.subscribe( | ||
36 | status => { | ||
37 | if (status === AuthStatus.LoggedIn) { | ||
38 | this.isLoggedIn = true | ||
39 | this.user = this.authService.getUser() | ||
40 | this.computeIsUserHasAdminAccess() | ||
41 | console.log('Logged in.') | ||
42 | } else if (status === AuthStatus.LoggedOut) { | ||
43 | this.isLoggedIn = false | ||
44 | this.user = undefined | ||
45 | this.computeIsUserHasAdminAccess() | ||
46 | console.log('Logged out.') | ||
47 | } else { | ||
48 | console.error('Unknown auth status: ' + status) | ||
49 | } | ||
50 | } | ||
51 | ) | ||
52 | } | ||
53 | |||
54 | getUserAvatarPath () { | ||
55 | return this.user.getAvatarPath() | ||
56 | } | ||
57 | |||
58 | isRegistrationAllowed () { | ||
59 | return this.serverService.getConfig().signup.allowed | ||
60 | } | ||
61 | |||
62 | getFirstAdminRightAvailable () { | ||
63 | const user = this.authService.getUser() | ||
64 | if (!user) return undefined | ||
65 | |||
66 | const adminRights = [ | ||
67 | UserRight.MANAGE_USERS, | ||
68 | UserRight.MANAGE_SERVER_FOLLOW, | ||
69 | UserRight.MANAGE_VIDEO_ABUSES, | ||
70 | UserRight.MANAGE_VIDEO_BLACKLIST | ||
71 | ] | ||
72 | |||
73 | for (const adminRight of adminRights) { | ||
74 | if (user.hasRight(adminRight)) { | ||
75 | return adminRight | ||
76 | } | ||
77 | } | ||
78 | |||
79 | return undefined | ||
80 | } | ||
81 | |||
82 | getFirstAdminRouteAvailable () { | ||
83 | const right = this.getFirstAdminRightAvailable() | ||
84 | |||
85 | return this.routesPerRight[right] | ||
86 | } | ||
87 | |||
88 | logout (event: Event) { | ||
89 | event.preventDefault() | ||
90 | |||
91 | this.authService.logout() | ||
92 | // Redirect to home page | ||
93 | this.router.navigate(['/videos/list']) | ||
94 | } | ||
95 | |||
96 | private computeIsUserHasAdminAccess () { | ||
97 | const right = this.getFirstAdminRightAvailable() | ||
98 | |||
99 | this.userHasAdminAccess = right !== undefined | ||
100 | } | ||
101 | } | ||