]>
Commit | Line | Data |
---|---|---|
3fa9efa0 | 1 | import { Injectable } from '@angular/core' |
9df52d66 | 2 | import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router' |
dd24f1bb C |
3 | import { RouterSetting } from './' |
4 | import { PeerTubeRouterService } from './peertube-router.service' | |
489290b8 | 5 | |
2f5d2ec5 | 6 | @Injectable() |
489290b8 C |
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) { | |
dd24f1bb C |
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) | |
489290b8 C |
86 | } |
87 | } |