+ private async injectBroadcastMessage () {
+ this.broadcastMessage = null
+ this.screenService.isBroadcastMessageDisplayed = false
+
+ const messageConfig = this.serverConfig.broadcastMessage
+
+ if (messageConfig.enabled) {
+ // Already dismissed this message?
+ if (messageConfig.dismissable && localStorage.getItem(AppComponent.BROADCAST_MESSAGE_KEY) === messageConfig.message) {
+ return
+ }
+
+ const classes: { [id in BroadcastMessageLevel]: string } = {
+ info: 'alert-info',
+ warning: 'alert-warning',
+ error: 'alert-danger'
+ }
+
+ this.broadcastMessage = {
+ message: await this.markdownService.unsafeMarkdownToHTML(messageConfig.message, true),
+ dismissable: messageConfig.dismissable,
+ class: classes[messageConfig.level]
+ }
+
+ this.screenService.isBroadcastMessageDisplayed = true
+ }
+ }
+
+ private injectJS () {
+ // Inject JS
+ if (this.serverConfig.instance.customizations.javascript) {
+ try {
+ /* eslint-disable no-eval */
+ eval(this.serverConfig.instance.customizations.javascript)
+ } catch (err) {
+ console.error('Cannot eval custom JavaScript.', err)
+ }
+ }
+ }
+
+ private injectCSS () {
+ const headStyle = document.querySelector('style.custom-css-style')
+ if (headStyle) headStyle.parentNode.removeChild(headStyle)
+
+ // We test customCSS if the admin removed the css
+ if (this.customCSS || this.serverConfig.instance.customizations.css) {
+ const styleTag = '<style>' + this.serverConfig.instance.customizations.css + '</style>'
+ this.customCSS = this.domSanitizer.bypassSecurityTrustHtml(styleTag)
+ }
+ }
+
+ private openModalsIfNeeded () {
+ const userSub = this.authService.userInformationLoaded
+ .pipe(
+ delay(0), // Wait for modals creations
+ map(() => this.authService.getUser())
+ )
+
+ // Admin modal
+ userSub.pipe(
+ filter(user => user.role === UserRole.ADMINISTRATOR)
+ ).subscribe(user => this.openAdminModalsIfNeeded(user))
+
+ // Account modal
+ userSub.pipe(
+ filter(user => user.role !== UserRole.ADMINISTRATOR)
+ ).subscribe(user => this.openAccountModalsIfNeeded(user))
+ }
+
+ private openAdminModalsIfNeeded (user: User) {
+ if (this.adminWelcomeModal.shouldOpen(user)) {
+ return this.adminWelcomeModal.show()
+ }
+
+ if (!this.instanceConfigWarningModal.shouldOpenByUser(user)) return
+
+ forkJoin([
+ this.serverService.getConfig().pipe(first()),
+ this.instanceService.getAbout().pipe(first())
+ ]).subscribe(([ config, about ]) => {
+ if (this.instanceConfigWarningModal.shouldOpen(config, about)) {
+ this.instanceConfigWarningModal.show(about)
+ }
+ })
+ }
+
+ private openAccountModalsIfNeeded (user: User) {
+ if (this.accountSetupWarningModal.shouldOpen(user)) {
+ this.accountSetupWarningModal.show(user)
+ }
+ }
+
+ private initHotkeys () {
+ this.hotkeysService.add([
+ new Hotkey([ '/', 's' ], (event: KeyboardEvent): boolean => {
+ document.getElementById('search-video').focus()
+ return false
+ }, undefined, $localize`Focus the search bar`),
+
+ new Hotkey('b', (event: KeyboardEvent): boolean => {
+ this.menu.toggleMenu()
+ return false
+ }, undefined, $localize`Toggle the left menu`),
+
+ new Hotkey('g o', (event: KeyboardEvent): boolean => {
+ this.router.navigate([ '/videos/overview' ])
+ return false
+ }, undefined, $localize`Go to the discover videos page`),
+
+ new Hotkey('g t', (event: KeyboardEvent): boolean => {
+ this.router.navigate([ '/videos/trending' ])
+ return false
+ }, undefined, $localize`Go to the trending videos page`),
+
+ new Hotkey('g r', (event: KeyboardEvent): boolean => {
+ this.router.navigate([ '/videos/recently-added' ])
+ return false
+ }, undefined, $localize`Go to the recently added videos page`),
+
+ new Hotkey('g l', (event: KeyboardEvent): boolean => {
+ this.router.navigate([ '/videos/local' ])
+ return false
+ }, undefined, $localize`Go to the local videos page`),
+
+ new Hotkey('g u', (event: KeyboardEvent): boolean => {
+ this.router.navigate([ '/videos/upload' ])
+ return false
+ }, undefined, $localize`Go to the videos upload page`)
+ ])
+ }
+
+ private loadUser () {
+ const tokens = this.userLocalStorage.getTokens()
+ if (!tokens) return
+
+ const user = this.userLocalStorage.getLoggedInUser()
+ if (!user) return