Skip to content
Snippets Groups Projects
Commit 5c7dbeb6 authored by jojohoch's avatar jojohoch
Browse files

[player] Refactor IntersectionDetector

* Use IntersectionDetector for intersectionDetection directive
* remove unnecessary input 'index' from page component
parent 1f659a1b
No related branches found
No related tags found
No related merge requests found
......@@ -3,11 +3,14 @@ import { EventEmitter } from '@angular/core';
export class IntersectionDetector {
intersectionObserver!: IntersectionObserver;
elements: { id: string, element: Element }[] = [];
root!: Document;
intersecting = new EventEmitter<string>();
root!: Document | HTMLElement;
constraint!: string;
intersecting = new EventEmitter<string | null>();
constructor(root: Document) {
constructor(root: Document | HTMLElement,
constraint: string) {
this.root = root;
this.constraint = constraint;
this.initIntersectionObserver();
}
......@@ -21,23 +24,39 @@ export class IntersectionDetector {
});
}, {
root: this.root,
rootMargin: '0px 0px 0px 0px'
rootMargin: this.constraint
}
);
}
observe(id: string, element: Element): void {
this.elements.push({ id, element });
observe(element: Element, id?: string): void {
if (id) {
this.elements.push({ id, element });
}
this.intersectionObserver.observe(element);
}
private intersectionDetected(element: Element):void {
unobserve(id: string): void {
const elementIndex = this.elements.findIndex(e => e.id === id);
if (elementIndex > -1) {
const element = this.elements[elementIndex];
this.intersectionObserver.unobserve(element.element);
this.elements.splice(elementIndex, 1);
}
}
disconnect(element: Element): void {
this.intersectionObserver.unobserve(element);
this.intersectionObserver.disconnect();
}
private intersectionDetected(element: Element): void {
const intersectedElementIndex = this.elements.findIndex(e => e.element === element);
if (intersectedElementIndex > -1) {
const intersectedElement = this.elements[intersectedElementIndex];
this.intersecting.emit(intersectedElement.id);
this.intersectionObserver.unobserve(intersectedElement.element);
this.elements.splice(intersectedElementIndex, 1);
} else {
this.intersecting.emit();
}
}
}
......@@ -27,7 +27,6 @@
[style.margin.px]="alwaysVisiblePage.margin">
<div class="mat-tab-label">{{'alwaysVisiblePage' | translate}}</div>
<app-page [parentArrayIndex]="alwaysVisibleUnitPageIndex"
[index]="alwaysVisibleUnitPageIndex"
[parentForm]="parentForm"
[isLastPage]="false"
[pagesContainer]="alwaysVisiblePageContainer"
......@@ -68,7 +67,6 @@
<div [style.margin.px]="page.margin"
[style.max-width]="page.hasMaxWidth ? page.maxWidth + 'px' : '100%'">
<app-page [parentArrayIndex]="scrollPagesIndices[i]"
[index]="scrollPagesIndices[i]"
[parentForm]="parentForm"
[isLastPage]="last"
[pagesContainer]="pagesContainer"
......@@ -95,7 +93,6 @@
{{'pageIndication' | translate: {index: i + 1} }}
</div>
<app-page [parentArrayIndex]="scrollPagesIndices[i]"
[index]="scrollPagesIndices[i]"
[parentForm]="parentForm"
[pagesContainer]="pagesContainer"
[page]="page"
......
<div appIntersectionDetection
detectionType="top"
[intersectionContainer]="pagesContainer"
(intersecting)="onIntersection($event)">
(intersecting)="onIntersection()">
<app-section *ngFor="let section of page.sections; let i = index"
[parentForm]="pageForm"
[parentArrayIndex]="i"
......@@ -18,5 +18,5 @@
<div appIntersectionDetection
detectionType="bottom"
[intersectionContainer]="pagesContainer"
(intersecting)="onIntersection($event)"
(intersecting)="onIntersection()"
></div>
......@@ -16,8 +16,6 @@ export class PageComponent implements OnInit {
@Input() isLastPage!: boolean;
@Input() parentForm!: FormGroup;
@Input() parentArrayIndex!: number;
@Input() index!: number;
@Input() pagesContainer!: HTMLElement;
@Output() selectedIndexChange = new EventEmitter<number>();
......@@ -40,12 +38,7 @@ export class PageComponent implements OnInit {
});
}
onIntersection(detectionType: 'top' | 'bottom'): void {
if (detectionType === 'bottom') {
this.unitStateService.addPresentedPage(this.index);
}
if (detectionType === 'top' || this.isLastPage) {
this.selectedIndexChange.emit(this.index);
}
onIntersection(): void {
this.selectedIndexChange.emit(this.parentArrayIndex);
}
}
import {
Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output
} from '@angular/core';
import { IntersectionDetector } from '../classes/intersection-detector';
@Directive({
selector: '[appIntersectionDetection]'
})
export class IntersectionDetectionDirective implements OnInit, OnDestroy {
@Input() detectionType!: 'top' | 'bottom';
@Output() intersecting = new EventEmitter<'top' | 'bottom'>();
@Output() intersecting = new EventEmitter();
@Input() intersectionContainer!: HTMLElement;
intersectionObserver!: IntersectionObserver;
private constraint!: string;
intersectionDetector!: IntersectionDetector;
constructor(private elementRef: ElementRef) {}
ngOnInit(): void {
this.constraint = this.detectionType === 'top' ? '0px 0px -95% 0px' : '-95% 0px 0px 0px';
this.initIntersectionObserver();
}
initIntersectionObserver(): void {
this.intersectionObserver = new IntersectionObserver(
(entries: IntersectionObserverEntry[]): void => entries.forEach(entry => {
if (entry.isIntersecting) {
this.intersecting.emit(this.detectionType);
}
}), {
root: this.intersectionContainer,
rootMargin: this.constraint
}
);
this.intersectionObserver.observe(this.elementRef.nativeElement);
const constraint = this.detectionType === 'top' ? '0px 0px 0px 0px' : '-95% 0px 0px 0px';
this.intersectionDetector = new IntersectionDetector(this.intersectionContainer, constraint);
this.intersectionDetector.observe(this.elementRef.nativeElement);
this.intersectionDetector.intersecting.subscribe(() => {
this.intersecting.emit();
});
}
ngOnDestroy(): void {
this.intersectionObserver.unobserve(this.elementRef.nativeElement);
this.intersectionObserver.disconnect();
this.intersectionDetector.disconnect(this.elementRef.nativeElement);
}
}
......@@ -20,7 +20,7 @@ export class UnitStateService {
unitStateElementCodes!: UnitStateElementCode[];
constructor(@Inject(DOCUMENT) private document: Document) {
this.intersectionDetector = new IntersectionDetector(document);
this.intersectionDetector = new IntersectionDetector(document, '0px 0px 0px 0px');
}
getUnitStateElement(id: string): UnitStateElementCode | undefined {
......@@ -57,10 +57,11 @@ export class UnitStateService {
registerElement(element: { id: string, value: InputElementValue }, domElement: Element): void {
this.addUnitStateElementCode(element.id, element.value);
this.intersectionDetector.observe(element.id, domElement);
this.intersectionDetector.observe(domElement, element.id);
this.intersectionDetector.intersecting
.subscribe((id: string) => {
this.changeElementStatus({ id: id, status: 'DISPLAYED' });
this.intersectionDetector.unobserve(id);
});
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment