diff --git a/src/app/app.component.html b/src/app/app.component.html
index 319b11d..cbf22d7 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,7 +1,8 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 9f30793..9c7b79e 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,4 +1,5 @@
import { Component } from '@angular/core';
+import { LoaderService } from './services/loader.service';
@Component({
selector: 'app-root',
@@ -6,5 +7,5 @@ import { Component } from '@angular/core';
styleUrls: ['./app.component.scss']
})
export class AppComponent {
- title = 'my-portfolio';
+ constructor(public loaderSvc: LoaderService) {}
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 8270401..3784c61 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,6 +1,6 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
-import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
+import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ContactSidebarComponent } from './contact-sidebar/contact-sidebar.component';
@@ -11,12 +11,13 @@ import { ProjectsComponent } from './projects/projects.component';
import { BlogComponent } from './blog/blog.component';
import { ContactComponent } from './contact/contact.component';
import { AppRoutingModule } from './app-routing.module';
-import { AuthInterceptor } from './http-interceptors/auth.interceptor';
import { httpInterceptorProviders } from './http-interceptors';
+import { SpinnerComponent } from './spinner/spinner.component';
@NgModule({
declarations: [
AppComponent,
+ SpinnerComponent,
ContactSidebarComponent,
NavbarComponent,
AboutComponent,
diff --git a/src/app/http-interceptors/index.ts b/src/app/http-interceptors/index.ts
index b5e66cd..ababa5a 100644
--- a/src/app/http-interceptors/index.ts
+++ b/src/app/http-interceptors/index.ts
@@ -1,7 +1,9 @@
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { AuthInterceptor } from "./auth.interceptor";
+import { LoadingInterceptor } from "./loading.interceptor";
export const httpInterceptorProviders = [
- {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true}
+ {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
+ {provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true}
]
\ No newline at end of file
diff --git a/src/app/http-interceptors/loading.interceptor.ts b/src/app/http-interceptors/loading.interceptor.ts
new file mode 100644
index 0000000..470744d
--- /dev/null
+++ b/src/app/http-interceptors/loading.interceptor.ts
@@ -0,0 +1,27 @@
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import { Observable, finalize } from "rxjs";
+import { LoaderService } from "../services/loader.service";
+
+@Injectable()
+export class LoadingInterceptor implements HttpInterceptor {
+
+ private totalRequests: number = 0;
+
+ constructor(private loadingSvc: LoaderService) { }
+
+ intercept(req: HttpRequest, next: HttpHandler): Observable> {
+ this.totalRequests++;
+ this.loadingSvc.setLoading(true);
+ return next.handle(req).pipe(
+ finalize(
+ () => {
+ this.totalRequests--;
+ if (this.totalRequests == 0) {
+ this.loadingSvc.setLoading(false);
+ }
+ }
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/app/services/loader.service.spec.ts b/src/app/services/loader.service.spec.ts
new file mode 100644
index 0000000..aef6961
--- /dev/null
+++ b/src/app/services/loader.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { LoaderService } from './loader.service';
+
+describe('LoaderService', () => {
+ let service: LoaderService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(LoaderService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/services/loader.service.ts b/src/app/services/loader.service.ts
new file mode 100644
index 0000000..ec2d0ca
--- /dev/null
+++ b/src/app/services/loader.service.ts
@@ -0,0 +1,16 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class LoaderService {
+ private loading: boolean = false;
+
+ setLoading(loading: boolean){
+ this.loading = loading;
+ }
+
+ getLoading(): boolean{
+ return this.loading;
+ }
+}
diff --git a/src/app/spinner/spinner.component.html b/src/app/spinner/spinner.component.html
new file mode 100644
index 0000000..d1bd03e
--- /dev/null
+++ b/src/app/spinner/spinner.component.html
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/app/spinner/spinner.component.scss b/src/app/spinner/spinner.component.scss
new file mode 100644
index 0000000..c4bb107
--- /dev/null
+++ b/src/app/spinner/spinner.component.scss
@@ -0,0 +1,65 @@
+.cssload-container {
+ position: fixed;
+ width: 100%;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ z-index: 9999;
+}
+
+.cssload-speeding-wheel {
+ content: "";
+ display: block;
+ position: absolute;
+ left: 48%;
+ top: 40%;
+ width: 63px;
+ height: 63px;
+ margin: 0 auto;
+ border: 4px solid hsl(45, 54%, 58%);
+ border-radius: 50%;
+ border-left-color: transparent;
+ border-right-color: transparent;
+ animation: cssload-spin 500ms infinite linear;
+ -o-animation: cssload-spin 500ms infinite linear;
+ -ms-animation: cssload-spin 500ms infinite linear;
+ -webkit-animation: cssload-spin 500ms infinite linear;
+ -moz-animation: cssload-spin 500ms infinite linear;
+}
+
+@keyframes cssload-spin {
+ 100% {
+ transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-o-keyframes cssload-spin {
+ 100% {
+ -o-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-ms-keyframes cssload-spin {
+ 100% {
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-webkit-keyframes cssload-spin {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-moz-keyframes cssload-spin {
+ 100% {
+ -moz-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
\ No newline at end of file
diff --git a/src/app/spinner/spinner.component.spec.ts b/src/app/spinner/spinner.component.spec.ts
new file mode 100644
index 0000000..5e92051
--- /dev/null
+++ b/src/app/spinner/spinner.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SpinnerComponent } from './spinner.component';
+
+describe('SpinnerComponent', () => {
+ let component: SpinnerComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [SpinnerComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(SpinnerComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/spinner/spinner.component.ts b/src/app/spinner/spinner.component.ts
new file mode 100644
index 0000000..cfdbecf
--- /dev/null
+++ b/src/app/spinner/spinner.component.ts
@@ -0,0 +1,14 @@
+import { Component, ViewEncapsulation } from '@angular/core';
+import { LoaderService } from '../services/loader.service';
+
+@Component({
+ selector: 'app-spinner',
+ templateUrl: './spinner.component.html',
+ styleUrl: './spinner.component.scss',
+ encapsulation: ViewEncapsulation.ShadowDom
+})
+export class SpinnerComponent {
+
+ constructor(public loader: LoaderService) {
+ }
+}