|
1 | | -import { Injectable } from '@angular/core'; |
2 | | -import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; |
| 1 | +import {inject, Injectable} from '@angular/core'; |
| 2 | +import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router'; |
| 3 | +import {BookBrowserScrollService} from '../features/book/components/book-browser/book-browser-scroll.service'; |
3 | 4 |
|
4 | 5 | @Injectable({ |
5 | 6 | providedIn: 'root', |
6 | 7 | }) |
7 | 8 | export class CustomReuseStrategy implements RouteReuseStrategy { |
8 | 9 | private storedRoutes = new Map<string, DetachedRouteHandle>(); |
| 10 | + private scrollService = inject(BookBrowserScrollService); |
| 11 | + |
| 12 | + private readonly BOOK_BROWSER_PATHS = [ |
| 13 | + 'all-books', |
| 14 | + 'unshelved-books', |
| 15 | + 'library/:libraryId/books', |
| 16 | + 'shelf/:shelfId/books', |
| 17 | + 'magic-shelf/:magicShelfId/books' |
| 18 | + ]; |
| 19 | + |
| 20 | + private readonly BOOK_DETAILS_PATH = 'book/:bookId'; |
| 21 | + |
| 22 | + private getRouteKey(route: ActivatedRouteSnapshot): string { |
| 23 | + const path = route.routeConfig?.path || ''; |
| 24 | + return this.scrollService.createKey(path, route.params); |
| 25 | + } |
| 26 | + |
| 27 | + private isBookBrowserRoute(route: ActivatedRouteSnapshot): boolean { |
| 28 | + const path = route.routeConfig?.path; |
| 29 | + return this.BOOK_BROWSER_PATHS.includes(path || ''); |
| 30 | + } |
| 31 | + |
| 32 | + private isBookDetailsRoute(route: ActivatedRouteSnapshot): boolean { |
| 33 | + return route.routeConfig?.path === this.BOOK_DETAILS_PATH; |
| 34 | + } |
9 | 35 |
|
10 | | - // Only detach the route if it's for the book details page |
11 | 36 | shouldDetach(route: ActivatedRouteSnapshot): boolean { |
12 | | - return route.routeConfig?.path === 'book/:id'; // Match the path of the route you want to reuse |
| 37 | + return this.isBookBrowserRoute(route); |
13 | 38 | } |
14 | 39 |
|
15 | | - // Store the route component instance when detaching |
16 | 40 | store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void { |
17 | | - if (handle) { |
18 | | - // Save the handle if we are detaching this route |
19 | | - this.storedRoutes.set(route.routeConfig?.path || '', handle); |
| 41 | + if (handle && this.isBookBrowserRoute(route)) { |
| 42 | + const key = this.getRouteKey(route); |
| 43 | + this.storedRoutes.set(key, handle); |
20 | 44 | } |
21 | 45 | } |
22 | 46 |
|
23 | | - // Check if we should attach the route (reuse it) when navigating back to it |
24 | 47 | shouldAttach(route: ActivatedRouteSnapshot): boolean { |
25 | | - // Attach the route only if there's a stored instance for this route |
26 | | - return !!this.storedRoutes.get(route.routeConfig?.path || ''); |
| 48 | + if (!this.isBookBrowserRoute(route)) { |
| 49 | + return false; |
| 50 | + } |
| 51 | + const key = this.getRouteKey(route); |
| 52 | + return this.storedRoutes.has(key); |
27 | 53 | } |
28 | 54 |
|
29 | | - // Retrieve the stored route component instance |
30 | 55 | retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null { |
31 | | - return this.storedRoutes.get(route.routeConfig?.path || '') || null; |
| 56 | + const key = this.getRouteKey(route); |
| 57 | + const handle = this.storedRoutes.get(key) || null; |
| 58 | + |
| 59 | + if (handle) { |
| 60 | + const savedPosition = this.scrollService.getPosition(key); |
| 61 | + if (savedPosition !== undefined) { |
| 62 | + setTimeout(() => { |
| 63 | + const scrollElement = document.querySelector('.virtual-scroller'); |
| 64 | + if (scrollElement) { |
| 65 | + (scrollElement as HTMLElement).scrollTop = savedPosition; |
| 66 | + } |
| 67 | + }, 0); |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + return handle; |
32 | 72 | } |
33 | 73 |
|
34 | | - // Determine if the route should be reused based on its configuration |
35 | 74 | shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { |
36 | | - // Reuse the route if the path and parameters match |
37 | | - return future.routeConfig === curr.routeConfig && future.params['id'] === curr.params['id']; |
| 75 | + return future.routeConfig === curr.routeConfig && |
| 76 | + JSON.stringify(future.params) === JSON.stringify(curr.params); |
38 | 77 | } |
39 | 78 | } |
0 commit comments