]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/core/routing/custom-reuse-strategy.ts
Add ability for plugins to register client routes
[github/Chocobozzz/PeerTube.git] / client / src / app / core / routing / custom-reuse-strategy.ts
CommitLineData
0af2a8c5 1import { ComponentRef, Injectable } from '@angular/core'
9df52d66 2import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'
0af2a8c5
C
3import { DisableForReuseHook } from './disable-for-reuse-hook'
4import { PeerTubeRouterService, RouterSetting } from './peertube-router.service'
489290b8 5
2f5d2ec5 6@Injectable()
489290b8
C
7export class CustomReuseStrategy implements RouteReuseStrategy {
8 storedRouteHandles = new Map<string, DetachedRouteHandle>()
9 recentlyUsed: string
10
11 private readonly MAX_SIZE = 2
12
13 // Decides if the route should be stored
14 shouldDetach (route: ActivatedRouteSnapshot): boolean {
15 return this.isReuseEnabled(route)
16 }
17
18 // Store the information for the route we're destructing
19 store (route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
20 if (!handle) return
21
22 const key = this.generateKey(route)
23 this.recentlyUsed = key
24
0af2a8c5 25 console.log('Storing component %s to reuse later.', key)
489290b8 26
0af2a8c5
C
27 const componentRef = (handle as any).componentRef as ComponentRef<DisableForReuseHook>
28 componentRef.instance.disableForReuse()
29 componentRef.changeDetectorRef.detectChanges()
489290b8
C
30
31 this.storedRouteHandles.set(key, handle)
32
33 this.gb()
34 }
35
36 // Return true if we have a stored route object for the next route
37 shouldAttach (route: ActivatedRouteSnapshot): boolean {
38 const key = this.generateKey(route)
39 return this.isReuseEnabled(route) && this.storedRouteHandles.has(key)
40 }
41
42 // If we returned true in shouldAttach(), now return the actual route data for restoration
43 retrieve (route: ActivatedRouteSnapshot): DetachedRouteHandle {
44 if (!this.isReuseEnabled(route)) return undefined
45
46 const key = this.generateKey(route)
47 this.recentlyUsed = key
48
49 console.log('Reusing component %s.', key)
50
51 const handle = this.storedRouteHandles.get(key)
52 if (!handle) return handle;
53
54 (handle as any).componentRef.instance.enabledForReuse()
55
56 return handle
57 }
58
59 // Reuse the route if we're going to and from the same route
60 shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
d63e6d46 61 return future.routeConfig === curr.routeConfig && future.routeConfig?.data?.reloadOnSameNavigation !== true
489290b8
C
62 }
63
64 private gb () {
65 if (this.storedRouteHandles.size >= this.MAX_SIZE) {
66 this.storedRouteHandles.forEach((r, key) => {
67 if (key === this.recentlyUsed) return
68
69 console.log('Removing stored component %s.', key);
70
71 (r as any).componentRef.destroy()
72 this.storedRouteHandles.delete(key)
73 })
74 }
75 }
76
77 private generateKey (route: ActivatedRouteSnapshot) {
78 const reuse = route.data.reuse
79 if (!reuse) return undefined
80
81 return reuse.key + JSON.stringify(route.queryParams)
82 }
83
84 private isReuseEnabled (route: ActivatedRouteSnapshot) {
dd24f1bb
C
85 // Cannot use peertube router here because of cyclic router dependency
86 return route.data.reuse?.enabled &&
87 !!(route.queryParams[PeerTubeRouterService.ROUTE_SETTING_NAME] & RouterSetting.REUSE_COMPONENT)
489290b8
C
88 }
89}