diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 53d3f76..47816ce 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,10 +1,20 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { SEOService } from '@app/core/services'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) -export class AppComponent { +export class AppComponent implements OnInit { + title = 'DiscoTrip'; + + constructor( public seoService: SEOService ) { + } + + ngOnInit() { + this.seoService.start(); + } + } diff --git a/src/app/core/services/index.ts b/src/app/core/services/index.ts index 98c29a9..a632bde 100644 --- a/src/app/core/services/index.ts +++ b/src/app/core/services/index.ts @@ -1,2 +1,4 @@ export * from './auth/auth.service'; export * from './log/log.service'; +export * from './seo/seo.service'; +export * from './storage/storage.service'; diff --git a/src/app/core/services/seo/seo.service.spec.ts b/src/app/core/services/seo/seo.service.spec.ts new file mode 100644 index 0000000..e3050c5 --- /dev/null +++ b/src/app/core/services/seo/seo.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { SEOService } from './seo.service'; + +describe( 'SEOService', () => { + beforeEach( () => TestBed.configureTestingModule( {} ) ); + + it( 'should be created', () => { + const service: SEOService = TestBed.get( SEOService ); + expect( service ).toBeTruthy(); + } ); +} ); diff --git a/src/app/core/services/seo/seo.service.ts b/src/app/core/services/seo/seo.service.ts new file mode 100644 index 0000000..9bfd42f --- /dev/null +++ b/src/app/core/services/seo/seo.service.ts @@ -0,0 +1,77 @@ +import { Injectable } from '@angular/core'; +import { Meta, Title } from '@angular/platform-browser'; +import { environment } from '@env/environment'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { filter, map, mergeMap } from 'rxjs/operators'; + +@Injectable() +export class SEOService { + + private defaultTitle = 'Constat à l\'amiable automatique'; + private defaultDescription = 'Notre projet consiste à aider les automobilistes en automatisant le remplissage du constat. C2A est intégré dans les' + + 'véhicules et récupère lors d’un accident les données de celui-ci (chocs, vitesse, position) pour remplir le constat. L’automobiliste obtiendra' + + 'son constat rempli sur son téléphone et après avoir apposé les signatures, le constat sera envoyé aux assureurs.'; + private defaultNoIndex = false; + private defaultNoFollow = false; + + constructor( private title: Title, private meta: Meta, private router: Router, private activatedRoute: ActivatedRoute ) {} + + public start() { + this.meta.updateTag( { name: 'og:locale', contest: 'fr_FR' } ); + this.meta.updateTag( { name: 'og:site_name', contest: environment.appName } ); + this.meta.updateTag( { name: 'og:url', content: location.href } ); + this.routerListener(); + } + + private updateTitle( title: string ) { + this.title.setTitle( title ); + this.meta.updateTag( { name: 'og:title', content: title } ); + } + + private updateDescription( desc: string ) { + this.meta.updateTag( { name: 'description', content: desc } ); + this.meta.updateTag( { name: 'og:description', content: desc } ); + } + + private updateIndexFollow( noindex: boolean, nofollow: boolean ) { + let content = ''; + + content += ( !noindex ? '' : 'noindex' ); + content += ( content.length > 0 ? ', ' : '' ); + content += ( !nofollow ? '' : 'nofollow' ); + + if ( content.length > 0 ) { + this.meta.updateTag( { name: 'robots', content } ); + this.meta.updateTag( { name: 'googlebot', content } ); + } + } + + private setMetas( event: any ) { + event[ 'title' ] = ( !event[ 'title' ] ? this.defaultTitle : event[ 'title' ] ); + event[ 'description' ] = ( !event[ 'description' ] ? this.defaultDescription : event[ 'description' ] ); + event[ 'noindex' ] = ( !event[ 'noindex' ] ? this.defaultNoIndex : event[ 'noindex' ] ); + event[ 'nofollow' ] = ( !event[ 'nofollow' ] ? this.defaultNoFollow : event[ 'nofollow' ] ); + this.updateTitle( event[ 'title' ] + ' | C2A' ); + this.updateDescription( event[ 'description' ] ); + this.updateIndexFollow( event[ 'noindex' ], event[ 'nofollow' ] ); + } + + private routerListener() { + this.router.events + .pipe( + filter( ( event ) => event instanceof NavigationEnd ), + map( () => this.activatedRoute ), + map( ( route ) => { + while ( route.firstChild ) { + route = route.firstChild; + } + return route; + } ), + filter( ( route ) => route.outlet === 'primary' ), + mergeMap( ( route ) => route.data ) + ).subscribe( ( event ) => { + this.setMetas( event ); + } ); + } + +}