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'
7 export class CustomReuseStrategy implements RouteReuseStrategy {
8 storedRouteHandles = new Map<string, DetachedRouteHandle>()
11 private readonly MAX_SIZE = 2
13 // Decides if the route should be stored
14 shouldDetach (route: ActivatedRouteSnapshot): boolean {
15 return this.isReuseEnabled(route)
18 // Store the information for the route we're destructing
19 store (route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
22 const key = this.generateKey(route)
23 this.recentlyUsed = key
25 console.log('Storing component %s to reuse later.', key);
27 (handle as any).componentRef.instance.disableForReuse()
29 this.storedRouteHandles.set(key, handle)
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)
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
44 const key = this.generateKey(route)
45 this.recentlyUsed = key
47 console.log('Reusing component %s.', key)
49 const handle = this.storedRouteHandles.get(key)
50 if (!handle) return handle;
52 (handle as any).componentRef.instance.enabledForReuse()
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
63 if (this.storedRouteHandles.size >= this.MAX_SIZE) {
64 this.storedRouteHandles.forEach((r, key) => {
65 if (key === this.recentlyUsed) return
67 console.log('Removing stored component %s.', key);
69 (r as any).componentRef.destroy()
70 this.storedRouteHandles.delete(key)
75 private generateKey (route: ActivatedRouteSnapshot) {
76 const reuse = route.data.reuse
77 if (!reuse) return undefined
79 return reuse.key + JSON.stringify(route.queryParams)
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)