diff options
Diffstat (limited to 'client/src/app/menu')
-rw-r--r-- | client/src/app/menu/language-chooser.component.scss | 2 | ||||
-rw-r--r-- | client/src/app/menu/language-chooser.component.ts | 15 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.html | 99 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.scss | 200 | ||||
-rw-r--r-- | client/src/app/menu/menu.component.ts | 62 |
5 files changed, 290 insertions, 88 deletions
diff --git a/client/src/app/menu/language-chooser.component.scss b/client/src/app/menu/language-chooser.component.scss index 72deb3952..50d19fd1f 100644 --- a/client/src/app/menu/language-chooser.component.scss +++ b/client/src/app/menu/language-chooser.component.scss | |||
@@ -4,6 +4,8 @@ | |||
4 | .help-to-translate { | 4 | .help-to-translate { |
5 | @include peertube-button-link; | 5 | @include peertube-button-link; |
6 | @include orange-button; | 6 | @include orange-button; |
7 | |||
8 | border-radius: 0; | ||
7 | } | 9 | } |
8 | 10 | ||
9 | .modal-body { | 11 | .modal-body { |
diff --git a/client/src/app/menu/language-chooser.component.ts b/client/src/app/menu/language-chooser.component.ts index 43f622dfb..fb74cdf19 100644 --- a/client/src/app/menu/language-chooser.component.ts +++ b/client/src/app/menu/language-chooser.component.ts | |||
@@ -1,7 +1,9 @@ | |||
1 | import { Component, ElementRef, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, ViewChild, Inject, LOCALE_ID } from '@angular/core' |
2 | import { I18N_LOCALES } from '../../../../shared' | 2 | import { I18N_LOCALES } from '../../../../shared' |
3 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 3 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' |
4 | import { sortBy } from '@app/shared/misc/utils' | 4 | import { sortBy } from '@app/shared/misc/utils' |
5 | import { getCompleteLocale } from '@shared/models/i18n' | ||
6 | import { isOnDevLocale, getDevLocale } from '@app/shared/i18n/i18n-utils' | ||
5 | 7 | ||
6 | @Component({ | 8 | @Component({ |
7 | selector: 'my-language-chooser', | 9 | selector: 'my-language-chooser', |
@@ -13,7 +15,10 @@ export class LanguageChooserComponent { | |||
13 | 15 | ||
14 | languages: { id: string, label: string }[] = [] | 16 | languages: { id: string, label: string }[] = [] |
15 | 17 | ||
16 | constructor (private modalService: NgbModal) { | 18 | constructor ( |
19 | private modalService: NgbModal, | ||
20 | @Inject(LOCALE_ID) private localeId: string | ||
21 | ) { | ||
17 | const l = Object.keys(I18N_LOCALES) | 22 | const l = Object.keys(I18N_LOCALES) |
18 | .map(k => ({ id: k, label: I18N_LOCALES[k] })) | 23 | .map(k => ({ id: k, label: I18N_LOCALES[k] })) |
19 | 24 | ||
@@ -28,4 +33,10 @@ export class LanguageChooserComponent { | |||
28 | return window.location.origin + '/' + lang.id | 33 | return window.location.origin + '/' + lang.id |
29 | } | 34 | } |
30 | 35 | ||
36 | getCurrentLanguage () { | ||
37 | const english = 'English' | ||
38 | const locale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId) | ||
39 | if (locale) return I18N_LOCALES[locale] || english | ||
40 | return english | ||
41 | } | ||
31 | } | 42 | } |
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 790a8af00..399350616 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html | |||
@@ -11,31 +11,62 @@ | |||
11 | <div class="logged-in-username">{{ user.username }}</div> | 11 | <div class="logged-in-username">{{ user.username }}</div> |
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <div class="logged-in-more" ngbDropdown placement="bottom-right auto" container="body"> | 14 | <div class="logged-in-more" ngbDropdown placement="right-top auto" container="body" autoClose="outside"> |
15 | <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon> | 15 | <my-global-icon iconName="more-vertical" ngbDropdownToggle role="button"></my-global-icon> |
16 | 16 | ||
17 | <div ngbDropdownMenu> | 17 | <div ngbDropdownMenu> |
18 | <a *ngIf="user.account" [routerLink]="[ '/accounts', user.account.nameWithHost ]" class="dropdown-item"> | 18 | <a *ngIf="user.account" ngbDropdownItem ngbDropdownToggle class="dropdown-item" [routerLink]="[ '/accounts', user.account.nameWithHost ]"> |
19 | <my-global-icon iconName="go"></my-global-icon> <ng-container i18n>Public profile</ng-container> | 19 | <my-global-icon iconName="go"></my-global-icon> <ng-container i18n>Public profile</ng-container> |
20 | </a> | 20 | </a> |
21 | 21 | ||
22 | <div class="dropdown-divider"></div> | 22 | <div class="dropdown-divider"></div> |
23 | 23 | ||
24 | <a routerLink="/my-account" class="dropdown-item"> | 24 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account"> |
25 | <my-global-icon iconName="user"></my-global-icon> <ng-container i18n>Account settings</ng-container> | 25 | <my-global-icon iconName="user"></my-global-icon> <ng-container i18n>Account settings</ng-container> |
26 | </a> | 26 | </a> |
27 | 27 | ||
28 | <a routerLink="/my-account/video-channels" class="dropdown-item"> | 28 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account/video-channels"> |
29 | <my-global-icon iconName="folder"></my-global-icon> <ng-container i18n>Channels settings</ng-container> | 29 | <my-global-icon iconName="folder"></my-global-icon> <ng-container i18n>Channels settings</ng-container> |
30 | </a> | 30 | </a> |
31 | 31 | ||
32 | <div class="dropdown-divider"></div> | 32 | <div class="dropdown-divider"></div> |
33 | 33 | ||
34 | <a class="dropdown-item" href="https://joinpeertube.org/help" target="_blank" rel="noopener noreferrer"> | 34 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openLanguageChooser()"> |
35 | <my-global-icon iconName="help"></my-global-icon> <ng-container i18n>Help</ng-container> | 35 | <my-global-icon iconName="language"></my-global-icon> |
36 | <ng-container i18n>Interface: {{ language }}</ng-container> | ||
37 | <i class="ml-auto glyphicon glyphicon-menu-right"></i> | ||
36 | </a> | 38 | </a> |
37 | 39 | ||
38 | <a (click)="logout($event)" class="dropdown-item" href="#"> | 40 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account"> |
41 | <my-global-icon iconName="video-lang"></my-global-icon> | ||
42 | <ng-container i18n>Videos: {{ videoLanguages.join(', ') }}</ng-container> | ||
43 | <i class="ml-auto glyphicon glyphicon-menu-right"></i> | ||
44 | </a> | ||
45 | |||
46 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account"> | ||
47 | <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy === 'display' }" iconName="sensitive"></my-global-icon> | ||
48 | <my-global-icon class="hover-display-toggle" [ngClass]="{ 'not-displayed': user.nsfwPolicy !== 'display' }" iconName="unsensitive"></my-global-icon> | ||
49 | <ng-container i18n>Sensitive: {{ nsfwPolicy }}</ng-container> | ||
50 | <i class="ml-auto glyphicon glyphicon-menu-right"></i> | ||
51 | </a> | ||
52 | |||
53 | <a ngbDropdownItem class="dropdown-item" (click)="toggleUseP2P()"> | ||
54 | <my-global-icon iconName="p2p"></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 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" routerLink="/my-account"> | ||
60 | <my-global-icon iconName="more-horizontal"></my-global-icon> <ng-container i18n>More account settings</ng-container> | ||
61 | </a> | ||
62 | |||
63 | <div class="dropdown-divider"></div> | ||
64 | |||
65 | <a ngbDropdownItem ngbDropdownToggle class="dropdown-item" (click)="openHotkeysCheatSheet()"> | ||
66 | <i class="icon icon-shortcuts"></i> <ng-container i18n>Keyboard shortcuts</ng-container> | ||
67 | </a> | ||
68 | |||
69 | <a ngbDropdownItem ngbDropdownToggle (click)="logout($event)" class="dropdown-item" href="#"> | ||
39 | <my-global-icon iconName="sign-out"></my-global-icon> <ng-container i18n>Log out</ng-container> | 70 | <my-global-icon iconName="sign-out"></my-global-icon> <ng-container i18n>Log out</ng-container> |
40 | </a> | 71 | </a> |
41 | </div> | 72 | </div> |
@@ -100,32 +131,56 @@ | |||
100 | <ng-container i18n>Local</ng-container> | 131 | <ng-container i18n>Local</ng-container> |
101 | </a> | 132 | </a> |
102 | </div> | 133 | </div> |
134 | </div> | ||
103 | 135 | ||
136 | <div class="footer"> | ||
104 | <div class="panel-block"> | 137 | <div class="panel-block"> |
105 | <div class="block-title" i18n>MORE</div> | ||
106 | |||
107 | <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> | 138 | <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> |
108 | <my-global-icon iconName="administration"></my-global-icon> | 139 | <my-global-icon iconName="cog"></my-global-icon> |
109 | <ng-container i18n>Administration</ng-container> | 140 | <ng-container i18n>Administration</ng-container> |
110 | </a> | 141 | </a> |
111 | 142 | <a *ngIf="!isLoggedIn" (click)="openQuickSettings()"> | |
112 | <a routerLink="/about" routerLinkActive="active"> | 143 | <my-global-icon iconName="cog"></my-global-icon> |
113 | <my-global-icon iconName="about"></my-global-icon> | 144 | <ng-container i18n>Settings</ng-container> |
145 | </a> | ||
146 | <a routerLink="/about/instance"> | ||
147 | <my-global-icon iconName="help"></my-global-icon> | ||
114 | <ng-container i18n>About</ng-container> | 148 | <ng-container i18n>About</ng-container> |
115 | </a> | 149 | </a> |
116 | </div> | 150 | </div> |
117 | </div> | ||
118 | |||
119 | <div class="footer d-flex justify-content-between"> | ||
120 | <span class="language"> | ||
121 | <span tabindex="0" role="button" (keyup.enter)="openLanguageChooser()" (click)="openLanguageChooser()" i18n-title title="Change the language" class="icon icon-language"></span> | ||
122 | </span> | ||
123 | 151 | ||
124 | <span class="shortcuts"> | 152 | <div class="d-flex flex-column"> |
125 | <span tabindex="0" role="button" (keyup.enter)="openHotkeysCheatSheet()" (click)="openHotkeysCheatSheet()" i18n-title title="Show keyboard shortcuts" class="icon icon-shortcuts"></span> | 153 | <div class="footer-links"> |
126 | </span> | 154 | <a i18n routerLink="/about/instance">Contact</a> |
155 | <a i18n routerLink="/about/instance">Terms of Service</a> | ||
156 | <a i18n routerLink="/about/instance" fragment="statistics">Stats</a> | ||
157 | <a (click)="openLanguageChooser()" class="c-hand"> | ||
158 | <span i18n>Interface: {{ language }}</span> | ||
159 | </a> | ||
160 | </div> | ||
161 | <div class="footer-links"> | ||
162 | <a i18n href="https://joinpeertube.org/#you-are-a-video-maker" i18n-title title="Creator guide" target="_blank" rel="noopener noreferrer">Creators</a> | ||
163 | <a i18n href="https://docs.joinpeertube.org/#/contribute-getting-started" i18n-title title="PeerTube license" target="_blank" rel="noopener noreferrer">Contributors</a> | ||
164 | <a i18n routerLink="/about/peertube" i18n-title title="More information about privacy within PeerTube">Privacy</a> | ||
165 | <a i18n href="https://joinpeertube.org/faq" i18n-title title="Frequently asked questions about PeerTube" target="_blank" rel="noopener noreferrer">FAQ</a> | ||
166 | <a i18n href="https://docs.joinpeertube.org/api-rest-reference.html" i18n-title title="API documentation" target="_blank" rel="noopener noreferrer">API</a> | ||
167 | <a i18n href="https://joinpeertube.org/help" i18n-title title="Get help using PeerTube" target="_blank" rel="noopener noreferrer">Help</a> | ||
168 | <a (click)="openHotkeysCheatSheet()" class="c-hand" i18n>Shortcuts</a> | ||
169 | </div> | ||
170 | <div class="footer-copyleft"> | ||
171 | <small class="d-inline" i18n-title title="powered by PeerTube - CopyLeft 2015-2020"> | ||
172 | <a href="https://joinpeertube.org" i18n-title title="PeerTube website" target="_blank" rel="noopener noreferrer" i18n> | ||
173 | powered by PeerTube | ||
174 | </a> | ||
175 | <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/LICENSE" i18n-title title="PeerTube license" target="_blank" rel="noopener noreferrer"> | ||
176 | <span aria-label="copyleft" class="d-inline-block" style="transform: rotateY(180deg)">©</span> 2015-2020 | ||
177 | </a> | ||
178 | </small> | ||
179 | </div> | ||
180 | </div> | ||
127 | </div> | 181 | </div> |
128 | </menu> | 182 | </menu> |
129 | </div> | 183 | </div> |
130 | 184 | ||
131 | <my-language-chooser #languageChooserModal></my-language-chooser> | 185 | <my-language-chooser #languageChooserModal></my-language-chooser> |
186 | <my-quick-settings #quickSettingsModal></my-quick-settings> | ||
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss index 40c9a2b25..a4b1ec000 100644 --- a/client/src/app/menu/menu.component.scss +++ b/client/src/app/menu/menu.component.scss | |||
@@ -29,7 +29,7 @@ menu { | |||
29 | 29 | ||
30 | &.logged-in { | 30 | &.logged-in { |
31 | .panel-block { | 31 | .panel-block { |
32 | margin-bottom: 25px; | 32 | margin-bottom: 20px; |
33 | } | 33 | } |
34 | 34 | ||
35 | .block-title { | 35 | .block-title { |
@@ -88,22 +88,6 @@ menu { | |||
88 | @include apply-svg-color(var(--menuForegroundColor)); | 88 | @include apply-svg-color(var(--menuForegroundColor)); |
89 | } | 89 | } |
90 | } | 90 | } |
91 | |||
92 | .dropdown-item { | ||
93 | @include dropdown-with-icon-item; | ||
94 | |||
95 | my-global-icon { | ||
96 | width: 22px; | ||
97 | height: 22px; | ||
98 | |||
99 | &[iconName="sign-out"] { | ||
100 | position: relative; | ||
101 | right: -1px; | ||
102 | height: 21px; | ||
103 | width: 21px; | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | } | 91 | } |
108 | } | 92 | } |
109 | 93 | ||
@@ -143,7 +127,7 @@ menu { | |||
143 | } | 127 | } |
144 | 128 | ||
145 | .panel-block { | 129 | .panel-block { |
146 | margin-bottom: 45px; | 130 | margin-bottom: 15px; |
147 | 131 | ||
148 | a { | 132 | a { |
149 | @include disable-default-a-behaviour; | 133 | @include disable-default-a-behaviour; |
@@ -198,60 +182,162 @@ menu { | |||
198 | } | 182 | } |
199 | 183 | ||
200 | .footer { | 184 | .footer { |
201 | padding-bottom: 15px; | ||
202 | padding-left: $menu-lateral-padding; | ||
203 | padding-right: $menu-lateral-padding; | ||
204 | width: $menu-width; | 185 | width: $menu-width; |
186 | padding-bottom: 15px; | ||
205 | 187 | ||
206 | .language, .shortcuts, .color-palette { | 188 | & > div:not(.panel-block) { |
207 | display: inline-block; | 189 | padding-left: $menu-lateral-padding; |
208 | color: $menu-bottom-color; | 190 | padding-right: $menu-lateral-padding; |
209 | cursor: pointer; | 191 | row-gap: 1em; |
210 | font-size: 12px; | 192 | } |
211 | font-weight: $font-semibold; | ||
212 | 193 | ||
213 | .icon { | 194 | $footer-links-base-opacity: .8; |
214 | @include disable-outline; | ||
215 | @include icon(28px); | ||
216 | opacity: 0.9; | ||
217 | 195 | ||
218 | &.icon-language { | 196 | .footer-links { |
219 | position: relative; | 197 | display: inline-flex; |
220 | top: -1px; | 198 | flex-wrap: wrap; |
221 | width: 28px; | 199 | |
222 | height: 24px; | 200 | & > a { |
201 | @include disable-default-a-behaviour; | ||
223 | 202 | ||
224 | background-image: url('../../assets/images/menu/language.png'); | 203 | display: inline-block; |
204 | text-decoration: none; | ||
205 | color: var(--mainBackgroundColor); | ||
206 | opacity: $footer-links-base-opacity; | ||
207 | white-space: nowrap; | ||
208 | font-size: 90%; | ||
209 | font-weight: 500; | ||
210 | line-height: 1.4rem; | ||
211 | margin-right: 8px; | ||
212 | |||
213 | &.inline-global-icon { | ||
214 | display: inline-flex; | ||
215 | align-items: center; | ||
216 | white-space: nowrap; | ||
217 | height: 1.4rem; | ||
218 | |||
219 | my-global-icon { | ||
220 | @include apply-svg-color(var(--mainBackgroundColor)); | ||
221 | |||
222 | display: flex; | ||
223 | width: auto; | ||
224 | height: 90%; | ||
225 | margin-right: .2rem; | ||
226 | } | ||
225 | } | 227 | } |
228 | } | ||
229 | } | ||
226 | 230 | ||
227 | &.icon-shortcuts { | 231 | .footer-copyleft small a { |
228 | position: relative; | 232 | @include disable-default-a-behaviour; |
229 | top: -1px; | ||
230 | width: 24px; | ||
231 | height: 24px; | ||
232 | 233 | ||
233 | background-image: url('../../assets/images/menu/keyboard.png'); | 234 | color: var(--mainBackgroundColor); |
234 | filter: invert(100%); | 235 | opacity: $footer-links-base-opacity - .2; |
235 | } | 236 | } |
237 | } | ||
238 | } | ||
236 | 239 | ||
237 | &.icon-moonsun { | 240 | .dropdown-menu { |
238 | margin-left: 10px; | 241 | width: calc(100% + 40px); |
239 | position: relative; | 242 | } |
240 | top: -1px; | ||
241 | width: 24px; | ||
242 | height: 24px; | ||
243 | 243 | ||
244 | background-image: url('../../assets/images/menu/moonsun.svg'); | 244 | .dropdown-item { |
245 | } | 245 | @include dropdown-with-icon-item; |
246 | 246 | ||
247 | &:hover { | 247 | cursor: pointer; |
248 | opacity: 1; | 248 | display: flex; |
249 | } | 249 | align-items: center; |
250 | } | 250 | |
251 | i.glyphicon-menu-right { | ||
252 | opacity: .4; | ||
253 | } | ||
254 | |||
255 | my-global-icon { | ||
256 | &[iconName="cog"], | ||
257 | &[iconName="sign-out"] { | ||
258 | position: relative; | ||
259 | right: -2px; | ||
260 | height: 20px; | ||
261 | width: 20px; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | my-global-icon.not-displayed { | ||
266 | display: none; | ||
267 | } | ||
268 | |||
269 | &:hover { | ||
270 | my-global-icon.hover-display-toggle.not-displayed { | ||
271 | display: inherit; | ||
272 | } | ||
273 | my-global-icon.hover-display-toggle { | ||
274 | display: none; | ||
251 | } | 275 | } |
252 | } | 276 | } |
253 | } | 277 | } |
254 | 278 | ||
279 | .more-settings { | ||
280 | text-transform: uppercase; | ||
281 | font-size: 80%; | ||
282 | color: #6c757d; | ||
283 | } | ||
284 | |||
285 | .icon { | ||
286 | @include disable-outline; | ||
287 | @include icon(22px); | ||
288 | opacity: 0.8; | ||
289 | |||
290 | &.icon-shortcuts { | ||
291 | position: relative; | ||
292 | top: -1px; | ||
293 | margin-right: 10px; | ||
294 | |||
295 | background-image: url('../../assets/images/menu/keyboard.png'); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | input[type=checkbox]{ | ||
300 | position: absolute; | ||
301 | visibility: hidden; | ||
302 | } | ||
303 | |||
304 | label { | ||
305 | cursor: pointer; | ||
306 | text-indent: -9999px; | ||
307 | width: 35px; | ||
308 | height: 20px; | ||
309 | background: #cccccc; | ||
310 | display: block; | ||
311 | border-radius: 100px; | ||
312 | position: relative; | ||
313 | margin: 0; | ||
314 | |||
315 | &:after { | ||
316 | content: ''; | ||
317 | position: absolute; | ||
318 | top: 3px; | ||
319 | left: 3px; | ||
320 | width: 14px; | ||
321 | height: 14px; | ||
322 | background: var(--mainBackgroundColor); | ||
323 | border-radius: 50%; | ||
324 | transition: 0.3s ease-out; | ||
325 | } | ||
326 | |||
327 | &:active:after { | ||
328 | width: 40px; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | input:checked + label { | ||
333 | background: var(--mainColor); | ||
334 | |||
335 | &:after { | ||
336 | left: calc(100% - 3px); | ||
337 | transform: translateX(-100%); | ||
338 | } | ||
339 | } | ||
340 | |||
255 | @media screen and (max-width: $mobile-view) { | 341 | @media screen and (max-width: $mobile-view) { |
256 | .menu-wrapper { | 342 | .menu-wrapper { |
257 | width: 100% !important; | 343 | width: 100% !important; |
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts index 1d7651e78..5f3dfc52a 100644 --- a/client/src/app/menu/menu.component.ts +++ b/client/src/app/menu/menu.component.ts | |||
@@ -1,10 +1,13 @@ | |||
1 | import { Component, OnInit, ViewChild } from '@angular/core' | 1 | import { Component, OnInit, ViewChild } from '@angular/core' |
2 | import { UserRight } from '../../../../shared/models/users/user-right.enum' | 2 | import { UserRight } from '../../../../shared/models/users/user-right.enum' |
3 | import { AuthService, AuthStatus, RedirectService, ServerService, ThemeService } from '../core' | 3 | import { AuthService, AuthStatus, RedirectService, ServerService } from '../core' |
4 | import { User } from '../shared/users/user.model' | 4 | import { User } from '@app/shared/users/user.model' |
5 | import { UserService } from '@app/shared/users/user.service' | ||
5 | import { LanguageChooserComponent } from '@app/menu/language-chooser.component' | 6 | import { LanguageChooserComponent } from '@app/menu/language-chooser.component' |
6 | import { HotkeysService } from 'angular2-hotkeys' | 7 | import { HotkeysService } from 'angular2-hotkeys' |
7 | import { ServerConfig } from '@shared/models' | 8 | import { ServerConfig, VideoConstant } from '@shared/models' |
9 | import { QuickSettingsModalComponent } from '@app/modal/quick-settings-modal.component' | ||
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 11 | ||
9 | @Component({ | 12 | @Component({ |
10 | selector: 'my-menu', | 13 | selector: 'my-menu', |
@@ -13,11 +16,14 @@ import { ServerConfig } from '@shared/models' | |||
13 | }) | 16 | }) |
14 | export class MenuComponent implements OnInit { | 17 | export class MenuComponent implements OnInit { |
15 | @ViewChild('languageChooserModal', { static: true }) languageChooserModal: LanguageChooserComponent | 18 | @ViewChild('languageChooserModal', { static: true }) languageChooserModal: LanguageChooserComponent |
19 | @ViewChild('quickSettingsModal', { static: true }) quickSettingsModal: QuickSettingsModalComponent | ||
16 | 20 | ||
17 | user: User | 21 | user: User |
18 | isLoggedIn: boolean | 22 | isLoggedIn: boolean |
23 | |||
19 | userHasAdminAccess = false | 24 | userHasAdminAccess = false |
20 | helpVisible = false | 25 | helpVisible = false |
26 | languages: VideoConstant<string>[] = [] | ||
21 | 27 | ||
22 | private serverConfig: ServerConfig | 28 | private serverConfig: ServerConfig |
23 | private routesPerRight: { [ role in UserRight ]?: string } = { | 29 | private routesPerRight: { [ role in UserRight ]?: string } = { |
@@ -31,9 +37,11 @@ export class MenuComponent implements OnInit { | |||
31 | 37 | ||
32 | constructor ( | 38 | constructor ( |
33 | private authService: AuthService, | 39 | private authService: AuthService, |
40 | private userService: UserService, | ||
34 | private serverService: ServerService, | 41 | private serverService: ServerService, |
35 | private redirectService: RedirectService, | 42 | private redirectService: RedirectService, |
36 | private hotkeysService: HotkeysService | 43 | private hotkeysService: HotkeysService, |
44 | private i18n: I18n | ||
37 | ) {} | 45 | ) {} |
38 | 46 | ||
39 | ngOnInit () { | 47 | ngOnInit () { |
@@ -63,9 +71,33 @@ export class MenuComponent implements OnInit { | |||
63 | } | 71 | } |
64 | ) | 72 | ) |
65 | 73 | ||
66 | this.hotkeysService.cheatSheetToggle.subscribe(isOpen => { | 74 | this.hotkeysService.cheatSheetToggle.subscribe(isOpen => this.helpVisible = isOpen) |
67 | this.helpVisible = isOpen | 75 | |
68 | }) | 76 | this.serverService.getVideoLanguages().subscribe(languages => this.languages = languages) |
77 | } | ||
78 | |||
79 | get language () { | ||
80 | return this.languageChooserModal.getCurrentLanguage() | ||
81 | } | ||
82 | |||
83 | get videoLanguages (): string[] { | ||
84 | if (!this.user) return | ||
85 | if (!this.user.videoLanguages) return [this.i18n('any language')] | ||
86 | return this.user.videoLanguages | ||
87 | .map(locale => this.langForLocale(locale)) | ||
88 | .map(value => value === undefined ? '?' : value) | ||
89 | } | ||
90 | |||
91 | get nsfwPolicy () { | ||
92 | if (!this.user) return | ||
93 | switch (this.user.nsfwPolicy) { | ||
94 | case 'do_not_list': | ||
95 | return this.i18n('hide') | ||
96 | case 'blur': | ||
97 | return this.i18n('blur') | ||
98 | case 'display': | ||
99 | return this.i18n('display') | ||
100 | } | ||
69 | } | 101 | } |
70 | 102 | ||
71 | isRegistrationAllowed () { | 103 | isRegistrationAllowed () { |
@@ -117,6 +149,22 @@ export class MenuComponent implements OnInit { | |||
117 | this.hotkeysService.cheatSheetToggle.next(!this.helpVisible) | 149 | this.hotkeysService.cheatSheetToggle.next(!this.helpVisible) |
118 | } | 150 | } |
119 | 151 | ||
152 | openQuickSettings () { | ||
153 | this.quickSettingsModal.show() | ||
154 | } | ||
155 | |||
156 | toggleUseP2P () { | ||
157 | if (!this.user) return | ||
158 | this.user.webTorrentEnabled = !this.user.webTorrentEnabled | ||
159 | this.userService.updateMyProfile({ | ||
160 | webTorrentEnabled: this.user.webTorrentEnabled | ||
161 | }).subscribe(() => this.authService.refreshUserInformation()) | ||
162 | } | ||
163 | |||
164 | langForLocale(localeId: string) { | ||
165 | return this.languages.find(lang => lang.id = localeId).label | ||
166 | } | ||
167 | |||
120 | private computeIsUserHasAdminAccess () { | 168 | private computeIsUserHasAdminAccess () { |
121 | const right = this.getFirstAdminRightAvailable() | 169 | const right = this.getFirstAdminRightAvailable() |
122 | 170 | ||