From 489290b8b16bede6ddfb773adad55dee6471ccfd Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 21 Mar 2019 16:49:46 +0100 Subject: Restore videos list components --- .../src/app/core/routing/custom-reuse-strategy.ts | 81 ++++++++++++++++++++++ .../src/app/core/routing/disable-for-reuse-hook.ts | 7 ++ 2 files changed, 88 insertions(+) create mode 100644 client/src/app/core/routing/custom-reuse-strategy.ts create mode 100644 client/src/app/core/routing/disable-for-reuse-hook.ts (limited to 'client/src/app/core') diff --git a/client/src/app/core/routing/custom-reuse-strategy.ts b/client/src/app/core/routing/custom-reuse-strategy.ts new file mode 100644 index 000000000..a9f61acec --- /dev/null +++ b/client/src/app/core/routing/custom-reuse-strategy.ts @@ -0,0 +1,81 @@ +import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router' + +export class CustomReuseStrategy implements RouteReuseStrategy { + storedRouteHandles = new Map() + recentlyUsed: string + + private readonly MAX_SIZE = 2 + + // Decides if the route should be stored + shouldDetach (route: ActivatedRouteSnapshot): boolean { + return this.isReuseEnabled(route) + } + + // Store the information for the route we're destructing + store (route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { + if (!handle) return + + const key = this.generateKey(route) + this.recentlyUsed = key + + console.log('Storing component %s to reuse later.', key); + + (handle as any).componentRef.instance.disableForReuse() + + this.storedRouteHandles.set(key, handle) + + this.gb() + } + + // Return true if we have a stored route object for the next route + shouldAttach (route: ActivatedRouteSnapshot): boolean { + const key = this.generateKey(route) + return this.isReuseEnabled(route) && this.storedRouteHandles.has(key) + } + + // If we returned true in shouldAttach(), now return the actual route data for restoration + retrieve (route: ActivatedRouteSnapshot): DetachedRouteHandle { + if (!this.isReuseEnabled(route)) return undefined + + const key = this.generateKey(route) + this.recentlyUsed = key + + console.log('Reusing component %s.', key) + + const handle = this.storedRouteHandles.get(key) + if (!handle) return handle; + + (handle as any).componentRef.instance.enabledForReuse() + + return handle + } + + // Reuse the route if we're going to and from the same route + shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { + return future.routeConfig === curr.routeConfig + } + + private gb () { + if (this.storedRouteHandles.size >= this.MAX_SIZE) { + this.storedRouteHandles.forEach((r, key) => { + if (key === this.recentlyUsed) return + + console.log('Removing stored component %s.', key); + + (r as any).componentRef.destroy() + this.storedRouteHandles.delete(key) + }) + } + } + + private generateKey (route: ActivatedRouteSnapshot) { + const reuse = route.data.reuse + if (!reuse) return undefined + + return reuse.key + JSON.stringify(route.queryParams) + } + + private isReuseEnabled (route: ActivatedRouteSnapshot) { + return route.data.reuse && route.data.reuse.enabled && route.queryParams['a-state'] + } +} diff --git a/client/src/app/core/routing/disable-for-reuse-hook.ts b/client/src/app/core/routing/disable-for-reuse-hook.ts new file mode 100644 index 000000000..c5eb5c578 --- /dev/null +++ b/client/src/app/core/routing/disable-for-reuse-hook.ts @@ -0,0 +1,7 @@ +export interface DisableForReuseHook { + + disableForReuse (): void + + enabledForReuse (): void + +} -- cgit v1.2.3