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.ts80
1 files changed, 18 insertions, 62 deletions
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index ed5cc53d9..dcc1f259f 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -1,10 +1,20 @@
1import { Hotkey, HotkeysService } from 'angular2-hotkeys' 1import { Hotkey, HotkeysService } from 'angular2-hotkeys'
2import { filter, map, pairwise, switchMap } from 'rxjs/operators' 2import { filter, map, switchMap } from 'rxjs/operators'
3import { DOCUMENT, getLocaleDirection, PlatformLocation, ViewportScroller } from '@angular/common' 3import { DOCUMENT, getLocaleDirection, PlatformLocation } from '@angular/common'
4import { AfterViewInit, Component, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core' 4import { AfterViewInit, Component, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core'
5import { DomSanitizer, SafeHtml } from '@angular/platform-browser' 5import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
6import { Event, GuardsCheckStart, NavigationEnd, RouteConfigLoadEnd, RouteConfigLoadStart, Router, Scroll } from '@angular/router' 6import { Event, GuardsCheckStart, RouteConfigLoadEnd, RouteConfigLoadStart, Router } from '@angular/router'
7import { AuthService, MarkdownService, RedirectService, ScreenService, ServerService, ThemeService, User } from '@app/core' 7import {
8 AuthService,
9 MarkdownService,
10 PeerTubeRouterService,
11 RedirectService,
12 ScreenService,
13 ScrollService,
14 ServerService,
15 ThemeService,
16 User
17} from '@app/core'
8import { HooksService } from '@app/core/plugins/hooks.service' 18import { HooksService } from '@app/core/plugins/hooks.service'
9import { PluginService } from '@app/core/plugins/plugin.service' 19import { PluginService } from '@app/core/plugins/plugin.service'
10import { CustomModalComponent } from '@app/modal/custom-modal.component' 20import { CustomModalComponent } from '@app/modal/custom-modal.component'
@@ -39,10 +49,10 @@ export class AppComponent implements OnInit, AfterViewInit {
39 constructor ( 49 constructor (
40 @Inject(DOCUMENT) private document: Document, 50 @Inject(DOCUMENT) private document: Document,
41 @Inject(LOCALE_ID) private localeId: string, 51 @Inject(LOCALE_ID) private localeId: string,
42 private viewportScroller: ViewportScroller,
43 private router: Router, 52 private router: Router,
44 private authService: AuthService, 53 private authService: AuthService,
45 private serverService: ServerService, 54 private serverService: ServerService,
55 private peertubeRouter: PeerTubeRouterService,
46 private pluginService: PluginService, 56 private pluginService: PluginService,
47 private instanceService: InstanceService, 57 private instanceService: InstanceService,
48 private domSanitizer: DomSanitizer, 58 private domSanitizer: DomSanitizer,
@@ -56,6 +66,7 @@ export class AppComponent implements OnInit, AfterViewInit {
56 private markdownService: MarkdownService, 66 private markdownService: MarkdownService,
57 private ngbConfig: NgbConfig, 67 private ngbConfig: NgbConfig,
58 private loadingBar: LoadingBarService, 68 private loadingBar: LoadingBarService,
69 private scrollService: ScrollService,
59 public menu: MenuService 70 public menu: MenuService
60 ) { 71 ) {
61 this.ngbConfig.animation = false 72 this.ngbConfig.animation = false
@@ -85,6 +96,7 @@ export class AppComponent implements OnInit, AfterViewInit {
85 } 96 }
86 97
87 this.initRouteEvents() 98 this.initRouteEvents()
99 this.scrollService.enableScrollRestoration()
88 100
89 this.injectJS() 101 this.injectJS()
90 this.injectCSS() 102 this.injectCSS()
@@ -132,66 +144,10 @@ export class AppComponent implements OnInit, AfterViewInit {
132 } 144 }
133 145
134 private initRouteEvents () { 146 private initRouteEvents () {
135 let resetScroll = true
136 const eventsObs = this.router.events 147 const eventsObs = this.router.events
137 148
138 const scrollEvent = eventsObs.pipe(filter((e: Event): e is Scroll => e instanceof Scroll))
139
140 // Handle anchors/restore position
141 scrollEvent.subscribe(e => {
142 // scrollToAnchor first to preserve anchor position when using history navigation
143 if (e.anchor) {
144 setTimeout(() => {
145 this.viewportScroller.scrollToAnchor(e.anchor)
146 })
147
148 return
149 }
150
151 if (e.position) {
152 return this.viewportScroller.scrollToPosition(e.position)
153 }
154
155 if (resetScroll) {
156 return this.viewportScroller.scrollToPosition([ 0, 0 ])
157 }
158 })
159
160 const navigationEndEvent = eventsObs.pipe(filter((e: Event): e is NavigationEnd => e instanceof NavigationEnd))
161
162 // When we add the a-state parameter, we don't want to alter the scroll
163 navigationEndEvent.pipe(pairwise())
164 .subscribe(([ e1, e2 ]) => {
165 try {
166 resetScroll = false
167
168 const previousUrl = new URL(window.location.origin + e1.urlAfterRedirects)
169 const nextUrl = new URL(window.location.origin + e2.urlAfterRedirects)
170
171 if (previousUrl.pathname !== nextUrl.pathname) {
172 resetScroll = true
173 return
174 }
175
176 const nextSearchParams = nextUrl.searchParams
177 nextSearchParams.delete('a-state')
178
179 const previousSearchParams = previousUrl.searchParams
180
181 nextSearchParams.sort()
182 previousSearchParams.sort()
183
184 if (nextSearchParams.toString() !== previousSearchParams.toString()) {
185 resetScroll = true
186 }
187 } catch (e) {
188 console.error('Cannot parse URL to check next scroll.', e)
189 resetScroll = true
190 }
191 })
192
193 // Plugin hooks 149 // Plugin hooks
194 navigationEndEvent.subscribe(e => { 150 this.peertubeRouter.getNavigationEndEvents().subscribe(e => {
195 this.hooks.runAction('action:router.navigation-end', 'common', { path: e.url }) 151 this.hooks.runAction('action:router.navigation-end', 'common', { path: e.url })
196 }) 152 })
197 153