Skip to content
Snippets Groups Projects
Unverified Commit 22df3f20 authored by AurianeStrasser2's avatar AurianeStrasser2 Committed by GitHub
Browse files

Merge pull request #23 from oser-cs/faster_site_progressbar

Affichage d'une progress bar lors de la navigation
parents 7da6e00e 0f14a86f
Branches
No related tags found
2 merge requests!22to be tested,!26Release first-users version to production
#progress {
position: fixed;
top: 0;
left: 0;
width: 100vw;
}
<app-splash *ngIf="!active"></app-splash>
<mat-progress-bar id="progress" mode="indeterminate" color="primary" *ngIf="loading"></mat-progress-bar>
<router-outlet></router-outlet>
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { Router,
Event as RouterEvent,
NavigationStart,
NavigationEnd,
NavigationCancel,
NavigationError ,
ActivatedRoute, } from '@angular/router';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { Observable, Subscription } from 'rxjs';
import { filter, map, mergeMap } from 'rxjs/operators';
import { LoaderService } from './core';
......@@ -18,8 +12,7 @@ import { LoaderService } from './core';
})
export class AppComponent implements OnInit, OnDestroy {
loading = true;
active = false;
loading = false;
sub = new Subscription();
constructor(
......@@ -29,42 +22,17 @@ export class AppComponent implements OnInit, OnDestroy {
private loaderService: LoaderService,
) { }
// Shows and hides the loading spinner during RouterEvent changes
navigationInterceptor(event: RouterEvent): void {
if (event instanceof NavigationStart) {
this.loading = true
}
if (event instanceof NavigationEnd) {
this.loading = false
}
// Set loading state to false in both of the below events to hide the spinner in case a request fails
if (event instanceof NavigationCancel) {
this.loading = false
}
if (event instanceof NavigationError) {
this.loading = false
}
}
ngOnInit() {
this.sub.add(
this.title$().subscribe(title => this.titleService.setTitle(title))
);
this.sub.add(
this.loaderService.loading().subscribe(loading => {
this.active = !loading;
this.loading = loading;
})
);
}
private active$(): Observable<boolean> {
return this.router.events.pipe(
filter(event => event instanceof NavigationStart || event instanceof NavigationEnd),
map(event => event instanceof NavigationEnd),
);
}
private title$(): Observable<string> {
return this.router.events.pipe(
// When a navigation finishes
......
......@@ -24,7 +24,6 @@ import { SignupPageComponent } from './signup-page/signup-page.component';
// Services
import { StudentService } from './signup-page/student.service';
import { MessageService } from './core';
import { SplashComponent } from './splash/splash.component';
registerLocaleData(localeFR);
......@@ -32,7 +31,6 @@ registerLocaleData(localeFR);
declarations: [
AppComponent,
SignupPageComponent,
SplashComponent,
],
imports: [
BrowserModule,
......
......@@ -6,7 +6,6 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MarkdownModule, MarkdownComponent, MarkdownPipe } from 'ngx-markdown';
import { TokenInterceptor } from './auth';
import { LoaderService } from './loader.service';
import { LoaderInterceptor } from './loader.interceptor';
import { MessageModule } from './messages';
import { FuzzyPipe, LineBreaksPipe } from './pipes';
import { NotFoundComponent } from './not-found';
......@@ -33,7 +32,6 @@ import { ErrorPageComponent } from './error-page';
providers: [
LoaderService,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true },
],
exports: [
MessageModule,
......
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { LoaderService } from './loader.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
constructor(private loaderService: LoaderService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loaderService.loading$.next(true);
return next.handle(request).pipe(
tap(() => this.loaderService.loading$.next(false)),
);
}
}
import { Injectable } from '@angular/core';
import { Router, NavigationStart, NavigationEnd, NavigationCancel } from '@angular/router';
import { Observable, BehaviorSubject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { map, debounceTime, tap, filter } from 'rxjs/operators';
@Injectable()
export class LoaderService {
public loading$: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(private router: Router) {}
public loading(): Observable<boolean> {
return this.loading$.asObservable().pipe(
// Prevent having multiple false's or multiple true's
distinctUntilChanged(),
return this.router.events.pipe(
filter(e => e instanceof NavigationStart || e instanceof NavigationEnd || e instanceof NavigationCancel),
debounceTime(100), // don't mark fast navigation changes as navigating
map((e) => e instanceof NavigationStart),
);
}
......
<div id="splash">
<mat-progress-bar mode="indeterminate" color="primary"></mat-progress-bar>
</div>
#splash {
z-index: 9999999;
position: fixed;
top: 0;
left: 0;
width: 100vw;
i {
background: white;
border-radius: 50%;
width: 1.3em;
height: 1.3em;
display: flex;
justify-content: center;
align-items: center;
}
}
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-splash',
templateUrl: './splash.component.html',
styleUrls: ['./splash.component.scss']
})
export class SplashComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment