]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/menu/menu.component.ts
Translated using Weblate (Kabyle)
[github/Chocobozzz/PeerTube.git] / client / src / app / menu / menu.component.ts
CommitLineData
f3081d64 1import { ViewportScroller } from '@angular/common'
67ed6552 2import { HotkeysService } from 'angular2-hotkeys'
dfe3f7b7
K
3import * as debug from 'debug'
4import { switchMap } from 'rxjs/operators'
8afc19a6 5import { Component, OnInit, ViewChild } from '@angular/core'
30d55e75 6import { Router } from '@angular/router'
f3081d64 7import { scrollToTop } from '@app/helpers'
30d55e75 8import { AuthService, AuthStatus, AuthUser, MenuService, RedirectService, ScreenService, ServerService, UserService } from '@app/core'
8afc19a6 9import { LanguageChooserComponent } from '@app/menu/language-chooser.component'
d3217560 10import { QuickSettingsModalComponent } from '@app/modal/quick-settings-modal.component'
67ed6552 11import { ServerConfig, UserRight, VideoConstant } from '@shared/models'
51a83970 12import { NgbDropdown, NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap'
43a3d281 13import { PeertubeModalService } from '@app/shared/shared-main/peertube-modal/peertube-modal.service'
602eb142 14
dfe3f7b7
K
15const logger = debug('peertube:menu:MenuComponent')
16
602eb142
C
17@Component({
18 selector: 'my-menu',
383bfc83 19 templateUrl: './menu.component.html',
dfe3f7b7 20 styleUrls: ['./menu.component.scss']
602eb142
C
21})
22export class MenuComponent implements OnInit {
f36da21e 23 @ViewChild('languageChooserModal', { static: true }) languageChooserModal: LanguageChooserComponent
d3217560 24 @ViewChild('quickSettingsModal', { static: true }) quickSettingsModal: QuickSettingsModalComponent
51a83970 25 @ViewChild('dropdown') dropdown: NgbDropdown
8afc19a6 26
dfe3f7b7 27 user: AuthUser
df98563e 28 isLoggedIn: boolean
d3217560 29
954605a8 30 userHasAdminAccess = false
4a216666 31 helpVisible = false
954605a8 32
111fdc26 33 videoLanguages: string[] = []
68f6c87a
C
34 nsfwPolicy: string
35
68f6c87a 36 currentInterfaceLanguage: string
111fdc26
C
37
38 private languages: VideoConstant<string>[] = []
ba430d75 39 private serverConfig: ServerConfig
dfe3f7b7 40 private routesPerRight: { [role in UserRight]?: string } = {
954605a8 41 [UserRight.MANAGE_USERS]: '/admin/users',
4610bc5b 42 [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends',
d95d1559 43 [UserRight.MANAGE_ABUSES]: '/admin/moderation/abuses',
3487330d 44 [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/moderation/video-blocks',
ad76628b
C
45 [UserRight.MANAGE_JOBS]: '/admin/jobs',
46 [UserRight.MANAGE_CONFIGURATION]: '/admin/config'
954605a8 47 }
602eb142
C
48
49 constructor (
f3081d64 50 private viewportScroller: ViewportScroller,
602eb142 51 private authService: AuthService,
d3217560 52 private userService: UserService,
db7af09b 53 private serverService: ServerService,
8c985ef5 54 private redirectService: RedirectService,
d3217560 55 private hotkeysService: HotkeysService,
30d55e75
K
56 private screenService: ScreenService,
57 private menuService: MenuService,
43a3d281 58 private modalService: PeertubeModalService,
51a83970 59 private dropdownConfig: NgbDropdownConfig,
30d55e75 60 private router: Router
51a83970
K
61 ) {
62 this.dropdownConfig.container = 'body'
63 }
64
65 get isInMobileView () {
66 return this.screenService.isInMobileView()
67 }
68
69 get dropdownContainer () {
70 if (this.isInMobileView) {
71 return null
72 } else {
73 return this.dropdownConfig.container
74 }
75 }
76
77 get language () {
78 return this.languageChooserModal.getCurrentLanguage()
79 }
ca4b1594 80
17119e4a
C
81 get instanceName () {
82 return this.serverConfig.instance.name
83 }
84
df98563e 85 ngOnInit () {
ba430d75
C
86 this.serverConfig = this.serverService.getTmpConfig()
87 this.serverService.getConfig()
88 .subscribe(config => this.serverConfig = config)
89
df98563e 90 this.isLoggedIn = this.authService.isLoggedIn()
dfe3f7b7
K
91 if (this.isLoggedIn === true) {
92 this.user = this.authService.getUser()
68f6c87a
C
93
94 this.computeNSFWPolicy()
dfe3f7b7
K
95 this.computeVideosLink()
96 }
97
98 this.computeAdminAccess()
602eb142 99
68f6c87a
C
100 this.currentInterfaceLanguage = this.languageChooserModal.getCurrentLanguage()
101
602eb142
C
102 this.authService.loginChangedSource.subscribe(
103 status => {
104 if (status === AuthStatus.LoggedIn) {
df98563e 105 this.isLoggedIn = true
b33f657c 106 this.user = this.authService.getUser()
dfe3f7b7
K
107
108 this.computeAdminAccess()
109 this.computeVideosLink()
110
111 logger('Logged in.')
602eb142 112 } else if (status === AuthStatus.LoggedOut) {
df98563e 113 this.isLoggedIn = false
b33f657c 114 this.user = undefined
dfe3f7b7
K
115
116 this.computeAdminAccess()
117
118 logger('Logged out.')
602eb142 119 } else {
df98563e 120 console.error('Unknown auth status: ' + status)
602eb142
C
121 }
122 }
df98563e 123 )
4a216666 124
111fdc26 125 this.hotkeysService.cheatSheetToggle
dfe3f7b7 126 .subscribe(isOpen => this.helpVisible = isOpen)
111fdc26
C
127
128 this.serverService.getVideoLanguages()
dfe3f7b7
K
129 .subscribe(languages => {
130 this.languages = languages
d3217560 131
dfe3f7b7
K
132 this.authService.userInformationLoaded
133 .subscribe(() => this.buildUserLanguages())
134 })
43a3d281 135
136 this.modalService.openQuickSettingsSubject
137 .subscribe(() => this.openQuickSettings())
d3217560
RK
138 }
139
291e8d3e 140 isRegistrationAllowed () {
ba430d75 141 return this.serverConfig.signup.allowed &&
dfe3f7b7 142 this.serverConfig.signup.allowedForCurrentIP
a184c71b
C
143 }
144
954605a8
C
145 getFirstAdminRightAvailable () {
146 const user = this.authService.getUser()
147 if (!user) return undefined
148
149 const adminRights = [
150 UserRight.MANAGE_USERS,
4610bc5b 151 UserRight.MANAGE_SERVER_FOLLOW,
d95d1559 152 UserRight.MANAGE_ABUSES,
3487330d 153 UserRight.MANAGE_VIDEO_BLACKLIST,
ad76628b
C
154 UserRight.MANAGE_JOBS,
155 UserRight.MANAGE_CONFIGURATION
954605a8
C
156 ]
157
158 for (const adminRight of adminRights) {
159 if (user.hasRight(adminRight)) {
160 return adminRight
161 }
162 }
163
164 return undefined
165 }
166
167 getFirstAdminRouteAvailable () {
168 const right = this.getFirstAdminRightAvailable()
169
170 return this.routesPerRight[right]
602eb142
C
171 }
172
b33f657c
C
173 logout (event: Event) {
174 event.preventDefault()
175
df98563e 176 this.authService.logout()
602eb142 177 // Redirect to home page
b1d40cff 178 this.redirectService.redirectToHomepage()
602eb142 179 }
954605a8 180
8afc19a6
C
181 openLanguageChooser () {
182 this.languageChooserModal.show()
183 }
184
4a216666
RK
185 openHotkeysCheatSheet () {
186 this.hotkeysService.cheatSheetToggle.next(!this.helpVisible)
187 }
188
d3217560
RK
189 openQuickSettings () {
190 this.quickSettingsModal.show()
191 }
192
193 toggleUseP2P () {
194 if (!this.user) return
195 this.user.webTorrentEnabled = !this.user.webTorrentEnabled
111fdc26
C
196
197 this.userService.updateMyProfile({ webTorrentEnabled: this.user.webTorrentEnabled })
dfe3f7b7 198 .subscribe(() => this.authService.refreshUserInformation())
d3217560
RK
199 }
200
8ada87ac 201 langForLocale (localeId: string) {
66357162 202 if (localeId === '_unknown') return $localize`Unknown`
bb3933ef 203
111fdc26
C
204 return this.languages.find(lang => lang.id === localeId).label
205 }
206
f3081d64 207 onActiveLinkScrollToAnchor (link: HTMLAnchorElement) {
30d55e75
K
208 const linkURL = link.getAttribute('href')
209 const linkHash = link.getAttribute('fragment')
210
211 // On same url without fragment restore top scroll position
212 if (!linkHash && this.router.url.includes(linkURL)) {
f3081d64 213 scrollToTop('smooth')
30d55e75
K
214 }
215
216 // On same url with fragment restore anchor scroll position
217 if (linkHash && this.router.url === linkURL) {
f3081d64 218 this.viewportScroller.scrollToAnchor(linkHash)
30d55e75
K
219 }
220
221 if (this.screenService.isInSmallView()) {
222 this.menuService.toggleMenu()
223 }
224 }
225
51a83970
K
226 // Lock menu scroll when menu scroll to avoid fleeing / detached dropdown
227 onMenuScrollEvent () {
228 document.querySelector('menu').scrollTo(0, 0)
229 }
230
231 onDropdownOpenChange (opened: boolean) {
232 if (this.screenService.isInMobileView()) return
233
234 // Close dropdown when window scroll to avoid dropdown quick jump for re-position
235 const onWindowScroll = () => {
56f08761 236 this.dropdown?.close()
51a83970
K
237 window.removeEventListener('scroll', onWindowScroll)
238 }
239
240 if (opened) {
241 window.addEventListener('scroll', onWindowScroll)
242 document.querySelector('menu').scrollTo(0, 0) // Reset menu scroll to easy lock
243 document.querySelector('menu').addEventListener('scroll', this.onMenuScrollEvent)
244 } else {
245 document.querySelector('menu').removeEventListener('scroll', this.onMenuScrollEvent)
246 }
247 }
248
111fdc26
C
249 private buildUserLanguages () {
250 if (!this.user) {
251 this.videoLanguages = []
252 return
253 }
254
255 if (!this.user.videoLanguages) {
66357162 256 this.videoLanguages = [$localize`any language`]
111fdc26
C
257 return
258 }
259
260 this.videoLanguages = this.user.videoLanguages
dfe3f7b7
K
261 .map(locale => this.langForLocale(locale))
262 .map(value => value === undefined ? '?' : value)
d3217560
RK
263 }
264
dfe3f7b7 265 private computeAdminAccess () {
954605a8
C
266 const right = this.getFirstAdminRightAvailable()
267
268 this.userHasAdminAccess = right !== undefined
269 }
dfe3f7b7
K
270
271 private computeVideosLink () {
272 this.authService.userInformationLoaded
273 .pipe(
274 switchMap(() => this.user.computeCanSeeVideosLink(this.userService.getMyVideoQuotaUsed()))
275 ).subscribe(res => {
276 if (res === true) logger('User can see videos link.')
277 else logger('User cannot see videos link.')
278 })
279 }
68f6c87a
C
280
281 private computeNSFWPolicy () {
282 if (!this.user) {
283 this.nsfwPolicy = null
284 return
285 }
286
287 switch (this.user.nsfwPolicy) {
288 case 'do_not_list':
289 this.nsfwPolicy = $localize`hide`
290 break
291
292 case 'blur':
293 this.nsfwPolicy = $localize`blur`
294 break
295
296 case 'display':
297 this.nsfwPolicy = $localize`display`
298 break
299 }
300 }
602eb142 301}