]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/core/routing/custom-reuse-strategy.ts
3000093a8df8f737d57342a7517b440cd02d922e
[github/Chocobozzz/PeerTube.git] / client / src / app / core / routing / custom-reuse-strategy.ts
1 import { Injectable } from '@angular/core'
2 import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'
3 import { RouterSetting } from './'
4 import { PeerTubeRouterService } from './peertube-router.service'
5
6 @Injectable()
7 export 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
25 console.log('Storing component %s to reuse later.', key);
26
27 (handle as any).componentRef.instance.disableForReuse()
28
29 this.storedRouteHandles.set(key, handle)
30
31 this.gb()
32 }
33
34 // Return true if we have a stored route object for the next route
35 shouldAttach (route: ActivatedRouteSnapshot): boolean {
36 const key = this.generateKey(route)
37 return this.isReuseEnabled(route) && this.storedRouteHandles.has(key)
38 }
39
40 // If we returned true in shouldAttach(), now return the actual route data for restoration
41 retrieve (route: ActivatedRouteSnapshot): DetachedRouteHandle {
42 if (!this.isReuseEnabled(route)) return undefined
43
44 const key = this.generateKey(route)
45 this.recentlyUsed = key
46
47 console.log('Reusing component %s.', key)
48
49 const handle = this.storedRouteHandles.get(key)
50 if (!handle) return handle;
51
52 (handle as any).componentRef.instance.enabledForReuse()
53
54 return handle
55 }
56
57 // Reuse the route if we're going to and from the same route
58 shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
59 return future.routeConfig === curr.routeConfig
60 }
61
62 private gb () {
63 if (this.storedRouteHandles.size >= this.MAX_SIZE) {
64 this.storedRouteHandles.forEach((r, key) => {
65 if (key === this.recentlyUsed) return
66
67 console.log('Removing stored component %s.', key);
68
69 (r as any).componentRef.destroy()
70 this.storedRouteHandles.delete(key)
71 })
72 }
73 }
74
75 private generateKey (route: ActivatedRouteSnapshot) {
76 const reuse = route.data.reuse
77 if (!reuse) return undefined
78
79 return reuse.key + JSON.stringify(route.queryParams)
80 }
81
82 private isReuseEnabled (route: ActivatedRouteSnapshot) {
83 // Cannot use peertube router here because of cyclic router dependency
84 return route.data.reuse?.enabled &&
85 !!(route.queryParams[PeerTubeRouterService.ROUTE_SETTING_NAME] & RouterSetting.REUSE_COMPONENT)
86 }
87 }