Commit b1940592 by Emile TAVERNE

Nettoyage de la lib de base

Ajout directive in viewport
parent 2ecc6343
......@@ -2,7 +2,8 @@
"name": "aitp-utils",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^7.2.0",
"@angular/core": "^7.2.0"
"@angular/common": "^4.0.0",
"@angular/core": "^4.0.0",
"rxjs": "^5.0.0"
}
}
\ No newline at end of file
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AitpUtilsComponent } from './aitp-utils.component';
describe('AitpUtilsComponent', () => {
let component: AitpUtilsComponent;
let fixture: ComponentFixture<AitpUtilsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AitpUtilsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AitpUtilsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'aiut-aitp-utils',
template: `
<p>
aitp-utils works!
</p>
`,
styles: []
})
export class AitpUtilsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
import { NgModule } from '@angular/core';
import { AitpUtilsComponent } from './aitp-utils.component';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import * as Directives from './directives';
import * as Services from './services';
@NgModule({
declarations: [AitpUtilsComponent],
imports: [
],
exports: [AitpUtilsComponent]
imports: [CommonModule],
declarations: [Directives.InViewportDirective],
providers: [Services.ViewportService],
exports: [Directives.InViewportDirective]
})
export class AitpUtilsModule { }
import { TestBed } from '@angular/core/testing';
import { AitpUtilsService } from './aitp-utils.service';
describe('AitpUtilsService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: AitpUtilsService = TestBed.get(AitpUtilsService);
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AitpUtilsService {
constructor() { }
}
import {Directive, ElementRef, EventEmitter, Inject, Input, OnDestroy, OnInit, Output, PLATFORM_ID,} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {filter, take} from 'rxjs/operators';
import {ViewportService} from '../services';
import {untilDestroy} from '../operators';
@Directive({
selector: '[aiutInViewport]',
})
export class InViewportDirective implements OnInit, OnDestroy {
@Input() public preRender = true;
@Input() public oneTime = false;
@Output() readonly inViewport = new EventEmitter<Partial<IntersectionObserverEntry>>();
constructor(
private readonly elementRef: ElementRef,
private viewportService: ViewportService,
@Inject(PLATFORM_ID) private platformId: Object,
) {
}
public ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
if (this.oneTime) {
this.viewportService
.observe(this.elementRef.nativeElement)
.pipe(
untilDestroy(this),
filter(entry => entry.intersectionRatio >= 0.5),
take(1),
)
.subscribe((entry: IntersectionObserverEntry) => {
this.inViewport.emit(entry);
});
} else {
this.viewportService
.observe(this.elementRef.nativeElement)
.pipe(untilDestroy(this))
.subscribe((entry: IntersectionObserverEntry) => {
this.inViewport.emit(entry);
});
}
} else {
if (this.preRender) {
this.inViewport.emit({isIntersecting: true, intersectionRatio: 1});
}
}
}
ngOnDestroy() {
}
}
export * from './in-viewport.directive';
export * from './until-destroy';
import {MonoTypeOperatorFunction, Observable} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
// create a symbol identify the observable I add to
// the component so it doesn't conflict with anything.
// I need this so I'm able to add the desired behaviour to the component.
export const destroy$ = Symbol('destroy$');
/**
* An operator that takes until destroy it takes a components this a parameter
* returns a pipeable RxJS operator.
*/
export const untilDestroy = <T>(component: any): MonoTypeOperatorFunction<T> => {
if (component[destroy$] === undefined) {
// only hookup each component once.
addDestroyObservableToComponent(component);
}
// pipe in the takeUntil destroy$ and return the source unaltered
return takeUntil<T>(component[destroy$]);
};
/**
* @internal
*/
export function addDestroyObservableToComponent(component: any) {
component[destroy$] = new Observable<void>(observer => {
// keep track of the original destroy function,
// the user might do something in there
const orignalDestroy = component.ngOnDestroy;
if (orignalDestroy == null) {
// Angular does not support dynamic added destroy methods
// so make sure there is one.
throw new Error('untilDestroy operator needs the component to have an ngOnDestroy method');
}
// replace the ngOndestroy
component.ngOnDestroy = () => {
// fire off the destroy observable
observer.next();
// complete the observable
observer.complete();
// and at last, call the original destroy
orignalDestroy.call(component);
};
// return cleanup function.
return (_: any) => (component[destroy$] = undefined);
});
}
export * from './viewport.service';
import {Injectable} from '@angular/core';
import {Observable, Subject} from 'rxjs';
import {filter, finalize} from 'rxjs/operators';
@Injectable()
export class ViewportService {
private readonly options: IntersectionObserverInit = {
rootMargin: '0px 0px 0px 0px',
threshold: [0.5],
};
private observer: IntersectionObserver;
private callback$: Subject<IntersectionObserverEntry> = new Subject();
constructor() {
this.observer = new IntersectionObserver(this.handler.bind(this), this.options);
}
observe(element: Element): Observable<IntersectionObserverEntry> {
this.observer.observe(element);
return this.callback$.asObservable().pipe(
filter((entry: IntersectionObserverEntry) => entry.target === element),
finalize(() => this.observer.unobserve(element)),
);
}
private handler(entries: Array<IntersectionObserverEntry>): void {
entries.forEach(entry => this.callback$.next(entry));
}
}
......@@ -2,6 +2,7 @@
* Public API Surface of aitp-utils
*/
export * from './lib/aitp-utils.service';
export * from './lib/aitp-utils.component';
export * from './lib/aitp-utils.module';
export * from './lib/directives';
export * from './lib/operators';
export * from './lib/services';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment