Commits

Yura Bondarenko authored 03e1e468bd0
91770: Fix route-matching themes not resolving on first load/refresh
No tags

src/app/app.component.ts

Modified
5 5 ChangeDetectionStrategy,
6 6 Component,
7 7 HostListener,
8 8 Inject,
9 9 OnInit,
10 10 Optional,
11 11 PLATFORM_ID,
12 12 } from '@angular/core';
13 13 import {
14 14 ActivatedRouteSnapshot,
15 + ActivationEnd,
15 16 NavigationCancel,
16 17 NavigationEnd,
17 18 NavigationStart, ResolveEnd,
18 19 Router,
19 20 } from '@angular/router';
20 21
21 22 import { isEqual } from 'lodash';
22 23 import { BehaviorSubject, Observable, of } from 'rxjs';
23 24 import { select, Store } from '@ngrx/store';
24 25 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
189 190 this.cssService.addCSSVariable('sidebarItemsWidth', '250px');
190 191 this.cssService.addCSSVariable('collapsedSidebarWidth', '53.234px');
191 192 this.cssService.addCSSVariable('totalSidebarWidth', '303.234px');
192 193 // const vars = variables.locals || {};
193 194 // Object.keys(vars).forEach((name: string) => {
194 195 // this.cssService.addCSSVariable(name, vars[name]);
195 196 // })
196 197 }
197 198
198 199 ngAfterViewInit() {
199 - let resolveEndFound = false;
200 + let updatingTheme = false;
201 + let snapshot: ActivatedRouteSnapshot;
202 +
200 203 this.router.events.subscribe((event) => {
201 204 if (event instanceof NavigationStart) {
202 - resolveEndFound = false;
205 + updatingTheme = false;
203 206 this.distinctNext(this.isRouteLoading$, true);
204 - } else if (event instanceof ResolveEnd) {
205 - resolveEndFound = true;
206 - const activatedRouteSnapShot: ActivatedRouteSnapshot = event.state.root;
207 - this.themeService.updateThemeOnRouteChange$(event.urlAfterRedirects, activatedRouteSnapShot).pipe(
208 - switchMap((changed) => {
209 - if (changed) {
210 - return this.isThemeCSSLoading$;
211 - } else {
212 - return [false];
213 - }
214 - })
215 - ).subscribe((changed) => {
216 - this.distinctNext(this.isThemeLoading$, changed);
217 - });
218 - } else if (
219 - event instanceof NavigationEnd ||
220 - event instanceof NavigationCancel
221 - ) {
222 - if (!resolveEndFound) {
207 + } else if (event instanceof ResolveEnd) {
208 + // this is the earliest point where we have all the information we need
209 + // to update the theme, but this event is not emitted on first load
210 + this.updateTheme(event.urlAfterRedirects, event.state.root);
211 + updatingTheme = true;
212 + } else if (!updatingTheme && event instanceof ActivationEnd) {
213 + // if there was no ResolveEnd, keep track of the snapshot...
214 + snapshot = event.snapshot;
215 + } else if (event instanceof NavigationEnd) {
216 + if (!updatingTheme) {
217 + // ...and use it to update the theme on NavigationEnd instead
218 + this.updateTheme(event.urlAfterRedirects, snapshot);
219 + updatingTheme = true;
220 + }
221 + this.distinctNext(this.isRouteLoading$, false);
222 + } else if (event instanceof NavigationCancel) {
223 + if (!updatingTheme) {
223 224 this.distinctNext(this.isThemeLoading$, false);
224 225 }
225 226 this.distinctNext(this.isRouteLoading$, false);
226 227 }
227 228 });
228 229 }
229 230
231 + private updateTheme(urlAfterRedirects: string, snapshot: ActivatedRouteSnapshot): void {
232 + this.themeService.updateThemeOnRouteChange$(urlAfterRedirects, snapshot).pipe(
233 + switchMap((changed) => {
234 + if (changed) {
235 + return this.isThemeCSSLoading$;
236 + } else {
237 + return [false];
238 + }
239 + })
240 + ).subscribe((changed) => {
241 + this.distinctNext(this.isThemeLoading$, changed);
242 + });
243 + }
244 +
230 245 @HostListener('window:resize', ['$event'])
231 246 public onResize(event): void {
232 247 this.dispatchWindowSize(event.target.innerWidth, event.target.innerHeight);
233 248 }
234 249
235 250 private dispatchWindowSize(width, height): void {
236 251 this.store.dispatch(
237 252 new HostWindowResizeAction(width, height)
238 253 );
239 254 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut