jxycms
5/13/2019 - 7:23 AM

Loading screen

1. LoadingScreenComponent

import { Subscription } from 'rxjs';
import { Component, OnInit, OnDestroy, Output, EventEmitter, Input } from '@angular/core';
import { LoadingScreenService } from '../../services/loading-screen.service';
import { debounceTime } from 'rxjs/operators';


@Component({
  selector: 'loading-screen',
  templateUrl: './loading-screen.component.html',
  styleUrls: ['./loading-screen.component.css']
})
export class LoadingScreenComponent implements OnInit, OnDestroy {
  @Input('backDropWidth') backDropWidth: string;
  @Input('showBlurTable') showBlurTable: boolean;
  @Input('isScrolled') isScrolled: boolean;
  @Input('scrollAfterLoading') scrollAfterLoading: boolean;
  @Output() currentLoadingStatus = new EventEmitter<boolean>();


  loading: boolean = true;
  loadingSubscription: Subscription;
  currentWidth: string;
  showTable: boolean = false;

  constructor(
    private loadingScreenService: LoadingScreenService
  ) { }
  
  ngOnInit() {

    this.currentWidth = this.backDropWidth ? this.backDropWidth : '984';
    this.showTable = this.showBlurTable ? this.showBlurTable : false;

    this.loadingSubscription = this.loadingScreenService.loadingStatus.pipe(
      debounceTime(200)
    ).subscribe((value) => {

      this.loading = value;
      
      this.currentLoadingStatus.emit(value);

      //TODO: customize for subscriptions pages for now, need more input if other pages wanna use it
      // if (this.scrollAfterLoading) {
      //    $('#levelOne').animate({ scrollLeft: 250 }, 400);
      // }
    });
  }

  ngOnDestroy() {
    this.loadingSubscription.unsubscribe();
  }

}

2. css

/* .loading-screen-wrapper {
  z-index: 100000;
  position: absolute;
  background-color: rgba(255, 255, 255, 0.6);
  width: 100%;
  height: 100%;
  display: block;
} */

/* .loading-screen-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    
}

.loading-icon {
    background-image: url('/images/new_ui/dd-progress.gif');
    width: 220px;
    height: 220px;
    background-size: cover;
    float: left;
    background-position: center;
    background-repeat: no-repeat;
    background-size: 60%;
    top: 37%;
    position: absolute;
    transform: translate(0, -50%);
    margin-left: 18px;
} */


.loader {
    
    width: 220px;
    height: 220px;
    margin: auto;
    background-image: url('/images/new_ui/dd-progress.gif');
    position: relative;
    z-index: 1;
    top: 50%;
    transform: translate(0,-50%);
  }
  :host {
    min-width: auto;
    -webkit-box-flex: 0;
    -ms-flex: 0 0 auto;
    flex: 0 0 auto;
     /* height: 100%;  */
    width: 100%;
  }


  .loading-screen-wrapper {
    z-index: 100000;
    position: fixed;
    background-color: rgba(0,0,0,0.03);
    width: 984px;
    height: 100%;
    display: block;
    opacity: 1;
    top: 35px;
    transition: opacity .15s linear;
    margin-top: 50px;

  }

  .shared-outer-wrapper{
    background: #fff;
    border: 1px solid #e6e6e6;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-box-shadow: 0 2px 4px rgba(0,0,0,.1);
    box-shadow: 0 2px 4px rgba(0,0,0,.1);
  }
  .order-title-wrapper{
    border-bottom: 1px solid #e6e6e6;
      margin-bottom: 20px;
      line-height: 12px;
      padding-bottom: 20px;
      padding-left: 20px;
      padding-right: 20px;
      margin-left: auto;
      margin-right: auto;
      padding-top: 20px;
  }
  .order-content-wrapper{
    line-height: 12px;
    padding-bottom: 20px;
    padding-left: 20px;
    padding-right: 20px;
    margin-left: auto;
    margin-right: auto;
    border-bottom: 1px solid #e6e6e6;
    margin-bottom: 20px;
    text-align: left;
  }
  .scrolled {
    left: 180px;
  }
  .scrollAfterLoading {
    left: 450px;
  }
  
  .blur_header {
    height: 18px;

  }

  .blur_body {
    height: 18px;

  }

  .blur_text {
    background-color: #f1f1f1;
    width: 100%;
    height: 17px;
    display: block;
    color: transparent;
    text-shadow: 0 0 3px #a09f9d;
    transition: all 0.5s ease;
  }

  .animated {
    -webkit-animation-duration: .5s;
    animation-duration: .5s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-timing-function: linear;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
  }
  @-webkit-keyframes bounce {
    0%, 100% {
      -webkit-transform: translate(0);
    }
    50% {
      -webkit-transform: translate(-5px);
    }
  }
  @keyframes bounce {
    0%, 100% {
      transform: translate(0);
    }
    50% {
      transform: translate(-5px);
    }
  }
  .bounce {
    -webkit-animation-name: bounce;
    animation-name: bounce;
  }
 
  hr {
    position: relative;
    top: 92px;
    left: -300px;
    width: 200px;
  }

3. html


<div class="loading-screen-wrapper" [style.width.px]="currentWidth" [class.scrolled]="isScrolled" [class.scrollAfterLoading]="scrollAfterLoading">
  <div class="loader" ></div>
</div>
<div class="inner-subBlock-wrapper" *ngIf="showTable">
  <div class="shared-outer-wrapper">
     <table style="width:100%">
       <thead>
          <tr class="row order-title-wrapper">
             <th class="col blur_header"><span class="blur_text animated bounce"></span></th>
             <th class="col blur_header"><span class="blur_text animated bounce"></span></th>
             <th class="col blur_header"><span class="blur_text animated bounce"></span></th>
             <th class="col blur_header"><span class="blur_text animated bounce"></span></th>
          </tr>
       </thead>
       <tbody>
         <tr class="row order-content-wrapper">
           <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
           <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
           <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
           <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
         </tr>
         <tr class="row order-content-wrapper">
            <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
            <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
            <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
            <td class="col-md blur_body"><span class="blur_text animated bounce"></span></td>
          </tr>
       </tbody>
     </table>
  </div>
</div>

4. LoadingScreenInterceptor

import { Injectable } from "@angular/core";
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Observable } from "rxjs";
import { finalize } from "rxjs/operators";
import { LoadingScreenService } from "../../services/loading-screen.service";


@Injectable()
export class LoadingScreenInterceptor implements HttpInterceptor {

  activeRequests: number = 0;

  /**
   * URLs for which the loading screen should not be enabled
   */
  skippUrls = [
    
  ];

  constructor(private loadingScreenService: LoadingScreenService) {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let displayLoadingScreen = true;

    for (const skippUrl of this.skippUrls) {
      if (new RegExp(skippUrl).test(request.url)) {
        displayLoadingScreen = false;
        break;
      }
    }


    if (displayLoadingScreen) {
      if (this.activeRequests === 0) {
        this.loadingScreenService.startLoading();
      }
      this.activeRequests++;

      return next.handle(request).pipe(
        finalize(() => {
          this.activeRequests--;
          if (this.activeRequests === 0) {
            this.loadingScreenService.stopLoading();

          }
        })
      )
    } else {
      return next.handle(request);
    }
  };
}

5. service

import { Subject } from 'rxjs';
import { Injectable } from '@angular/core';

@Injectable()
export class LoadingScreenService {

  private _loading: boolean = false;
  loadingStatus: Subject<boolean> = new Subject<boolean>();

  get loading():boolean {
    return this._loading;
  }

  set loading(value) {
    this._loading = value;
    this.loadingStatus.next(value);
  }

  startLoading() {
    this.loading = true;
  }

  stopLoading() {
    this.loading = false;
  }

}


6. how to use

in html
<loading-screen *ngIf="!loadContent" [isScrolled]="true" [showBlurTable]="false" [backDropWidth]="1200"
      (currentLoadingStatus)="onLoading($event)"></loading-screen>
      
in component
loadContent: boolean = false;
ngOnInit() {
  this.loadContent = false; // start
  this.loadContent = true;  // stop
}

onLoading(currentLoadingStatus: boolean) {
  this.loadContent = !currentLoadingStatus;
}
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import { ShareService } from '../services/share.service';
import { LoadScreenService } from '../services/load-screen.service';
import { finalize } from 'rxjs/operators';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  activeRequests: number = 0;

  /**
   * URLs for which the loading screen should not be enabled
   */
  skippUrls = [

  ];

  constructor(private router: Router, private shareService: ShareService, private loadingScreenService: LoadScreenService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    let displayLoadingScreen = true;

    for (const skippUrl of this.skippUrls) {
      if (new RegExp(skippUrl).test(request.url)) {
        displayLoadingScreen = false;
        break;
      }
    }


    if (displayLoadingScreen) {
      if (this.activeRequests === 0) {
        this.loadingScreenService.startLoading();
      }
      this.activeRequests++;
      if (request.headers.get('No-Auth') == "True") {
        return next.handle(request.clone()).pipe(
          finalize(() => {
            this.activeRequests--;
            if (this.activeRequests === 0) {
              this.loadingScreenService.stopLoading();
            }
          })
        )
      }
      if (this.shareService.readCookie("userToken")) {
        return next.handle(
          request.clone(
            { headers: request.headers.set("Authorization", "Bearer " + this.shareService.readCookie("userToken")) }
          )
        ).pipe(
          finalize(() => {
            this.activeRequests--;
            if (this.activeRequests === 0) {
              this.loadingScreenService.stopLoading();
            }
          })
        )
      }
      else {
        this.router.navigateByUrl('/login');
      }
    } else {
      return next.handle(request).pipe(
        finalize(() => {
          this.activeRequests--;
          if (this.activeRequests === 0) {
            this.loadingScreenService.stopLoading();
          }
        })
      );
    }
  }
}