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