1 import { ViewportScroller } from '@angular/common'
2 import { HotkeysService } from 'angular2-hotkeys'
3 import * as debug from 'debug'
4 import { switchMap } from 'rxjs/operators'
5 import { Component, OnInit, ViewChild } from '@angular/core'
6 import { Router } from '@angular/router'
7 import { scrollToTop } from '@app/helpers'
8 import { AuthService, AuthStatus, AuthUser, MenuService, RedirectService, ScreenService, ServerService, UserService } from '@app/core'
9 import { LanguageChooserComponent } from '@app/menu/language-chooser.component'
10 import { QuickSettingsModalComponent } from '@app/modal/quick-settings-modal.component'
11 import { ServerConfig, UserRight, VideoConstant } from '@shared/models'
13 const logger = debug('peertube:menu:MenuComponent')
17 templateUrl: './menu.component.html',
18 styleUrls: ['./menu.component.scss']
20 export class MenuComponent implements OnInit {
21 @ViewChild('languageChooserModal', { static: true }) languageChooserModal: LanguageChooserComponent
22 @ViewChild('quickSettingsModal', { static: true }) quickSettingsModal: QuickSettingsModalComponent
27 userHasAdminAccess = false
30 videoLanguages: string[] = []
33 loggedInMorePlacement: string
35 currentInterfaceLanguage: string
37 private languages: VideoConstant<string>[] = []
38 private serverConfig: ServerConfig
39 private routesPerRight: { [role in UserRight]?: string } = {
40 [UserRight.MANAGE_USERS]: '/admin/users',
41 [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends',
42 [UserRight.MANAGE_ABUSES]: '/admin/moderation/abuses',
43 [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/moderation/video-blocks',
44 [UserRight.MANAGE_JOBS]: '/admin/jobs',
45 [UserRight.MANAGE_CONFIGURATION]: '/admin/config'
49 private viewportScroller: ViewportScroller,
50 private authService: AuthService,
51 private userService: UserService,
52 private serverService: ServerService,
53 private redirectService: RedirectService,
54 private hotkeysService: HotkeysService,
55 private screenService: ScreenService,
56 private menuService: MenuService,
57 private router: Router
61 return this.serverConfig.instance.name
65 this.serverConfig = this.serverService.getTmpConfig()
66 this.serverService.getConfig()
67 .subscribe(config => this.serverConfig = config)
69 this.isLoggedIn = this.authService.isLoggedIn()
70 if (this.isLoggedIn === true) {
71 this.user = this.authService.getUser()
73 this.computeNSFWPolicy()
74 this.computeVideosLink()
77 this.computeAdminAccess()
79 this.loggedInMorePlacement = this.screenService.isInMobileView()
83 this.currentInterfaceLanguage = this.languageChooserModal.getCurrentLanguage()
85 this.authService.loginChangedSource.subscribe(
87 if (status === AuthStatus.LoggedIn) {
88 this.isLoggedIn = true
89 this.user = this.authService.getUser()
91 this.computeAdminAccess()
92 this.computeVideosLink()
95 } else if (status === AuthStatus.LoggedOut) {
96 this.isLoggedIn = false
99 this.computeAdminAccess()
101 logger('Logged out.')
103 console.error('Unknown auth status: ' + status)
108 this.hotkeysService.cheatSheetToggle
109 .subscribe(isOpen => this.helpVisible = isOpen)
111 this.serverService.getVideoLanguages()
112 .subscribe(languages => {
113 this.languages = languages
115 this.authService.userInformationLoaded
116 .subscribe(() => this.buildUserLanguages())
120 isRegistrationAllowed () {
121 return this.serverConfig.signup.allowed &&
122 this.serverConfig.signup.allowedForCurrentIP
125 getFirstAdminRightAvailable () {
126 const user = this.authService.getUser()
127 if (!user) return undefined
129 const adminRights = [
130 UserRight.MANAGE_USERS,
131 UserRight.MANAGE_SERVER_FOLLOW,
132 UserRight.MANAGE_ABUSES,
133 UserRight.MANAGE_VIDEO_BLACKLIST,
134 UserRight.MANAGE_JOBS,
135 UserRight.MANAGE_CONFIGURATION
138 for (const adminRight of adminRights) {
139 if (user.hasRight(adminRight)) {
147 getFirstAdminRouteAvailable () {
148 const right = this.getFirstAdminRightAvailable()
150 return this.routesPerRight[right]
153 logout (event: Event) {
154 event.preventDefault()
156 this.authService.logout()
157 // Redirect to home page
158 this.redirectService.redirectToHomepage()
161 openLanguageChooser () {
162 this.languageChooserModal.show()
165 openHotkeysCheatSheet () {
166 this.hotkeysService.cheatSheetToggle.next(!this.helpVisible)
169 openQuickSettings () {
170 this.quickSettingsModal.show()
174 if (!this.user) return
175 this.user.webTorrentEnabled = !this.user.webTorrentEnabled
177 this.userService.updateMyProfile({ webTorrentEnabled: this.user.webTorrentEnabled })
178 .subscribe(() => this.authService.refreshUserInformation())
181 langForLocale (localeId: string) {
182 if (localeId === '_unknown') return $localize`Unknown`
184 return this.languages.find(lang => lang.id === localeId).label
187 onActiveLinkScrollToAnchor (link: HTMLAnchorElement) {
188 const linkURL = link.getAttribute('href')
189 const linkHash = link.getAttribute('fragment')
191 // On same url without fragment restore top scroll position
192 if (!linkHash && this.router.url.includes(linkURL)) {
193 scrollToTop('smooth')
196 // On same url with fragment restore anchor scroll position
197 if (linkHash && this.router.url === linkURL) {
198 this.viewportScroller.scrollToAnchor(linkHash)
201 if (this.screenService.isInSmallView()) {
202 this.menuService.toggleMenu()
206 private buildUserLanguages () {
208 this.videoLanguages = []
212 if (!this.user.videoLanguages) {
213 this.videoLanguages = [$localize`any language`]
217 this.videoLanguages = this.user.videoLanguages
218 .map(locale => this.langForLocale(locale))
219 .map(value => value === undefined ? '?' : value)
222 private computeAdminAccess () {
223 const right = this.getFirstAdminRightAvailable()
225 this.userHasAdminAccess = right !== undefined
228 private computeVideosLink () {
229 this.authService.userInformationLoaded
231 switchMap(() => this.user.computeCanSeeVideosLink(this.userService.getMyVideoQuotaUsed()))
233 if (res === true) logger('User can see videos link.')
234 else logger('User cannot see videos link.')
238 private computeNSFWPolicy () {
240 this.nsfwPolicy = null
244 switch (this.user.nsfwPolicy) {
246 this.nsfwPolicy = $localize`hide`
250 this.nsfwPolicy = $localize`blur`
254 this.nsfwPolicy = $localize`display`