]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/core/routing/scroll.service.ts
Update translations
[github/Chocobozzz/PeerTube.git] / client / src / app / core / routing / scroll.service.ts
CommitLineData
dd24f1bb
C
1import * as debug from 'debug'
2import { pairwise } from 'rxjs'
3import { ViewportScroller } from '@angular/common'
4import { Injectable } from '@angular/core'
5import { RouterSetting } from '../'
6import { PeerTubeRouterService } from './peertube-router.service'
42b40636 7import { logger } from '@root-helpers/logger'
dd24f1bb 8
42b40636 9const debugLogger = debug('peertube:main:ScrollService')
dd24f1bb
C
10
11@Injectable()
12export class ScrollService {
13
14 private resetScroll = true
15
16 constructor (
17 private viewportScroller: ViewportScroller,
18 private peertubeRouter: PeerTubeRouterService
19 ) { }
20
21 enableScrollRestoration () {
22 // We'll manage scroll restoration ourselves
23 this.viewportScroller.setHistoryScrollRestoration('manual')
24
25 this.consumeScroll()
26 this.produceScroll()
27 }
28
29 private produceScroll () {
30 // When we add the a-state parameter, we don't want to alter the scroll
31 this.peertubeRouter.getNavigationEndEvents().pipe(pairwise())
32 .subscribe(([ e1, e2 ]) => {
33 try {
34 this.resetScroll = false
35
36 const previousUrl = new URL(window.location.origin + e1.urlAfterRedirects)
37 const nextUrl = new URL(window.location.origin + e2.urlAfterRedirects)
38
39 if (previousUrl.pathname !== nextUrl.pathname) {
40 this.resetScroll = true
41 return
42 }
43
44 if (this.peertubeRouter.hasRouteSetting(RouterSetting.DISABLE_SCROLL_RESTORE)) {
45 this.resetScroll = false
46 return
47 }
48
49 // Remove route settings from the comparison
50 const nextSearchParams = nextUrl.searchParams
51 nextSearchParams.delete(PeerTubeRouterService.ROUTE_SETTING_NAME)
52
53 const previousSearchParams = previousUrl.searchParams
54
55 nextSearchParams.sort()
56 previousSearchParams.sort()
57
58 if (nextSearchParams.toString() !== previousSearchParams.toString()) {
59 this.resetScroll = true
60 }
42b40636
C
61 } catch (err) {
62 logger.error('Cannot parse URL to check next scroll.', err)
dd24f1bb
C
63 this.resetScroll = true
64 }
65 })
66 }
67
68 private consumeScroll () {
69 // Handle anchors/restore position
70 this.peertubeRouter.getScrollEvents().subscribe(e => {
42b40636 71 debugLogger('Will schedule scroll after router event %o.', { e, resetScroll: this.resetScroll })
dd24f1bb
C
72
73 // scrollToAnchor first to preserve anchor position when using history navigation
74 if (e.anchor) {
75 setTimeout(() => this.viewportScroller.scrollToAnchor(e.anchor))
76
77 return
78 }
79
80 if (e.position) {
81 setTimeout(() => this.viewportScroller.scrollToPosition(e.position))
82
83 return
84 }
85
86 if (this.resetScroll) {
87 return this.viewportScroller.scrollToPosition([ 0, 0 ])
88 }
89 })
90 }
91
92}