aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/app.component.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/app.component.ts')
-rw-r--r--client/src/app/app.component.ts131
1 files changed, 95 insertions, 36 deletions
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index c5c5a8f66..ad0588b99 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -1,13 +1,14 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { DomSanitizer, SafeHtml } from '@angular/platform-browser' 2import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
3import { GuardsCheckStart, NavigationEnd, Router } from '@angular/router' 3import { Event, GuardsCheckStart, NavigationEnd, Router, Scroll } from '@angular/router'
4import { AuthService, RedirectService, ServerService, ThemeService } from '@app/core' 4import { AuthService, RedirectService, ServerService, ThemeService } from '@app/core'
5import { is18nPath } from '../../../shared/models/i18n' 5import { is18nPath } from '../../../shared/models/i18n'
6import { ScreenService } from '@app/shared/misc/screen.service' 6import { ScreenService } from '@app/shared/misc/screen.service'
7import { skip, debounceTime } from 'rxjs/operators' 7import { debounceTime, filter, map, pairwise, skip } from 'rxjs/operators'
8import { HotkeysService, Hotkey } from 'angular2-hotkeys' 8import { Hotkey, HotkeysService } from 'angular2-hotkeys'
9import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
10import { fromEvent } from 'rxjs' 10import { fromEvent } from 'rxjs'
11import { ViewportScroller } from '@angular/common'
11 12
12@Component({ 13@Component({
13 selector: 'my-app', 14 selector: 'my-app',
@@ -22,6 +23,7 @@ export class AppComponent implements OnInit {
22 23
23 constructor ( 24 constructor (
24 private i18n: I18n, 25 private i18n: I18n,
26 private viewportScroller: ViewportScroller,
25 private router: Router, 27 private router: Router,
26 private authService: AuthService, 28 private authService: AuthService,
27 private serverService: ServerService, 29 private serverService: ServerService,
@@ -52,15 +54,6 @@ export class AppComponent implements OnInit {
52 ngOnInit () { 54 ngOnInit () {
53 document.getElementById('incompatible-browser').className += ' browser-ok' 55 document.getElementById('incompatible-browser').className += ' browser-ok'
54 56
55 this.router.events.subscribe(e => {
56 if (e instanceof NavigationEnd) {
57 const pathname = window.location.pathname
58 if (!pathname || pathname === '/' || is18nPath(pathname)) {
59 this.redirectService.redirectToHomepage(true)
60 }
61 }
62 })
63
64 this.authService.loadClientCredentials() 57 this.authService.loadClientCredentials()
65 58
66 if (this.isUserLoggedIn()) { 59 if (this.isUserLoggedIn()) {
@@ -81,15 +74,94 @@ export class AppComponent implements OnInit {
81 this.isMenuDisplayed = false 74 this.isMenuDisplayed = false
82 } 75 }
83 76
84 this.router.events.subscribe( 77 this.initRouteEvents()
85 e => { 78 this.injectJS()
86 // User clicked on a link in the menu, change the page 79 this.injectCSS()
87 if (e instanceof GuardsCheckStart && this.screenService.isInSmallView()) { 80
88 this.isMenuDisplayed = false 81 this.initHotkeys()
89 } 82
83 fromEvent(window, 'resize')
84 .pipe(debounceTime(200))
85 .subscribe(() => this.onResize())
86 }
87
88 isUserLoggedIn () {
89 return this.authService.isLoggedIn()
90 }
91
92 toggleMenu () {
93 this.isMenuDisplayed = !this.isMenuDisplayed
94 this.isMenuChangedByUser = true
95 }
96
97 onResize () {
98 this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
99 }
100
101 private initRouteEvents () {
102 let resetScroll = true
103 const eventsObs = this.router.events
104
105 const scrollEvent = eventsObs.pipe(filter((e: Event): e is Scroll => e instanceof Scroll))
106 const navigationEndEvent = eventsObs.pipe(filter((e: Event): e is NavigationEnd => e instanceof NavigationEnd))
107
108 scrollEvent.subscribe(e => {
109 if (e.position) {
110 return this.viewportScroller.scrollToPosition(e.position)
90 } 111 }
91 )
92 112
113 if (e.anchor) {
114 return this.viewportScroller.scrollToAnchor(e.anchor)
115 }
116
117 if (resetScroll) {
118 return this.viewportScroller.scrollToPosition([ 0, 0 ])
119 }
120 })
121
122 // When we add the a-state parameter, we don't want to alter the scroll
123 navigationEndEvent.pipe(pairwise())
124 .subscribe(([ e1, e2 ]) => {
125 try {
126 resetScroll = false
127
128 const previousUrl = new URL(window.location.origin + e1.url)
129 const nextUrl = new URL(window.location.origin + e2.url)
130
131 if (previousUrl.pathname !== nextUrl.pathname) {
132 resetScroll = true
133 return
134 }
135
136 const nextSearchParams = nextUrl.searchParams
137 nextSearchParams.delete('a-state')
138
139 const previousSearchParams = previousUrl.searchParams
140
141 nextSearchParams.sort()
142 previousSearchParams.sort()
143
144 if (nextSearchParams.toString() !== previousSearchParams.toString()) {
145 resetScroll = true
146 }
147 } catch (e) {
148 console.error('Cannot parse URL to check next scroll.', e)
149 resetScroll = true
150 }
151 })
152
153 navigationEndEvent.pipe(
154 map(() => window.location.pathname),
155 filter(pathname => !pathname || pathname === '/' || is18nPath(pathname))
156 ).subscribe(() => this.redirectService.redirectToHomepage(true))
157
158 eventsObs.pipe(
159 filter((e: Event): e is GuardsCheckStart => e instanceof GuardsCheckStart),
160 filter(() => this.screenService.isInSmallView())
161 ).subscribe(() => this.isMenuDisplayed = false) // User clicked on a link in the menu, change the page
162 }
163
164 private injectJS () {
93 // Inject JS 165 // Inject JS
94 this.serverService.configLoaded 166 this.serverService.configLoaded
95 .subscribe(() => { 167 .subscribe(() => {
@@ -104,7 +176,9 @@ export class AppComponent implements OnInit {
104 } 176 }
105 } 177 }
106 }) 178 })
179 }
107 180
181 private injectCSS () {
108 // Inject CSS if modified (admin config settings) 182 // Inject CSS if modified (admin config settings)
109 this.serverService.configLoaded 183 this.serverService.configLoaded
110 .pipe(skip(1)) // We only want to subscribe to reloads, because the CSS is already injected by the server 184 .pipe(skip(1)) // We only want to subscribe to reloads, because the CSS is already injected by the server
@@ -120,7 +194,9 @@ export class AppComponent implements OnInit {
120 this.customCSS = this.domSanitizer.bypassSecurityTrustHtml(styleTag) 194 this.customCSS = this.domSanitizer.bypassSecurityTrustHtml(styleTag)
121 } 195 }
122 }) 196 })
197 }
123 198
199 private initHotkeys () {
124 this.hotkeysService.add([ 200 this.hotkeysService.add([
125 new Hotkey(['/', 's'], (event: KeyboardEvent): boolean => { 201 new Hotkey(['/', 's'], (event: KeyboardEvent): boolean => {
126 document.getElementById('search-video').focus() 202 document.getElementById('search-video').focus()
@@ -155,22 +231,5 @@ export class AppComponent implements OnInit {
155 return false 231 return false
156 }, undefined, this.i18n('Toggle Dark theme')) 232 }, undefined, this.i18n('Toggle Dark theme'))
157 ]) 233 ])
158
159 fromEvent(window, 'resize')
160 .pipe(debounceTime(200))
161 .subscribe(() => this.onResize())
162 }
163
164 isUserLoggedIn () {
165 return this.authService.isLoggedIn()
166 }
167
168 toggleMenu () {
169 this.isMenuDisplayed = !this.isMenuDisplayed
170 this.isMenuChangedByUser = true
171 }
172
173 onResize () {
174 this.isMenuDisplayed = window.innerWidth >= 800 && !this.isMenuChangedByUser
175 } 234 }
176} 235}