diff options
Diffstat (limited to 'client/src/app/app.component.ts')
-rw-r--r-- | client/src/app/app.component.ts | 80 |
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 @@ | |||
1 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' | 1 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' |
2 | import { filter, map, pairwise, switchMap } from 'rxjs/operators' | 2 | import { filter, map, switchMap } from 'rxjs/operators' |
3 | import { DOCUMENT, getLocaleDirection, PlatformLocation, ViewportScroller } from '@angular/common' | 3 | import { DOCUMENT, getLocaleDirection, PlatformLocation } from '@angular/common' |
4 | import { AfterViewInit, Component, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core' | 4 | import { AfterViewInit, Component, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core' |
5 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' | 5 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' |
6 | import { Event, GuardsCheckStart, NavigationEnd, RouteConfigLoadEnd, RouteConfigLoadStart, Router, Scroll } from '@angular/router' | 6 | import { Event, GuardsCheckStart, RouteConfigLoadEnd, RouteConfigLoadStart, Router } from '@angular/router' |
7 | import { AuthService, MarkdownService, RedirectService, ScreenService, ServerService, ThemeService, User } from '@app/core' | 7 | import { |
8 | AuthService, | ||
9 | MarkdownService, | ||
10 | PeerTubeRouterService, | ||
11 | RedirectService, | ||
12 | ScreenService, | ||
13 | ScrollService, | ||
14 | ServerService, | ||
15 | ThemeService, | ||
16 | User | ||
17 | } from '@app/core' | ||
8 | import { HooksService } from '@app/core/plugins/hooks.service' | 18 | import { HooksService } from '@app/core/plugins/hooks.service' |
9 | import { PluginService } from '@app/core/plugins/plugin.service' | 19 | import { PluginService } from '@app/core/plugins/plugin.service' |
10 | import { CustomModalComponent } from '@app/modal/custom-modal.component' | 20 | import { 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 | ||