From 3b09148e6e97022ceb96c352ec94c7910896926a Mon Sep 17 00:00:00 2001
From: jojohoch <joachim.hoch@iqb.hu-berlin.de>
Date: Mon, 18 Oct 2021 16:18:42 +0200
Subject: [PATCH] [player] Implement 'DISPLAYED' status detection for each
 element

---
 .../src/app/components/page/page.component.ts  |  6 +++---
 .../components/section/section.component.html  | 10 ++++++++++
 .../components/section/section.component.ts    | 12 ++++++++++--
 .../intersection-detection.directive.ts        | 18 +++++++++++++-----
 4 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/projects/player/src/app/components/page/page.component.ts b/projects/player/src/app/components/page/page.component.ts
index 41085dc6f..43b820f80 100644
--- a/projects/player/src/app/components/page/page.component.ts
+++ b/projects/player/src/app/components/page/page.component.ts
@@ -40,11 +40,11 @@ export class PageComponent implements OnInit {
     });
   }
 
-  onIntersection(detectionType: 'top' | 'bottom'): void {
-    if (detectionType === 'bottom') {
+  onIntersection(detection: { detectionType: 'top' | 'bottom' | 'full', id: string }): void {
+    if (detection.detectionType === 'bottom') {
       this.unitStateService.addPresentedPage(this.index);
     }
-    if (detectionType === 'top' || this.isLastPage) {
+    if (detection.detectionType === 'top' || this.isLastPage) {
       this.selectedIndexChange.emit(this.index);
     }
   }
diff --git a/projects/player/src/app/components/section/section.component.html b/projects/player/src/app/components/section/section.component.html
index 46054d621..cfb69b543 100644
--- a/projects/player/src/app/components/section/section.component.html
+++ b/projects/player/src/app/components/section/section.component.html
@@ -3,6 +3,11 @@
 <ng-template #staticElements>
   <ng-container *ngFor="let element of section.elements; let i = index">
     <app-element
+        appIntersectionDetection
+        detectionType="full"
+        [intersectionContainer]="document"
+        [id]="element.id"
+        (intersecting)="onIntersection($event)"
         [style.display]="'block'"
         [style.overflow]="'auto'"
         [style.width.px]="element.width"
@@ -25,6 +30,11 @@
        [style.grid-auto-rows]="section.autoRowSize ? 'auto' : undefined">
     <ng-container *ngFor="let element of section.elements; let i = index">
       <app-element
+          appIntersectionDetection
+          detectionType="full"
+          [intersectionContainer]="document"
+          [id]="element.id"
+          (intersecting)="onIntersection($event)"
           [style.min-width.px]="element.width"
           [style.min-height.px]="element.height"
           [style.margin-left.px]="element.marginLeft"
diff --git a/projects/player/src/app/components/section/section.component.ts b/projects/player/src/app/components/section/section.component.ts
index f863ea8ef..4d6283c4b 100644
--- a/projects/player/src/app/components/section/section.component.ts
+++ b/projects/player/src/app/components/section/section.component.ts
@@ -1,9 +1,11 @@
 import {
-  Component, Input, OnInit
+  Component, Inject, Input, OnInit
 } from '@angular/core';
 import { FormBuilder, FormGroup } from '@angular/forms';
+import { DOCUMENT } from '@angular/common';
 import { FormService } from '../../../../../common/form.service';
 import { Section } from '../../../../../common/models/section';
+import { UnitStateService } from '../../services/unit-state.service';
 
 @Component({
   selector: 'app-section',
@@ -17,7 +19,9 @@ export class SectionComponent implements OnInit {
   sectionForm!: FormGroup;
 
   constructor(private formService: FormService,
-              private formBuilder: FormBuilder) {
+              private formBuilder: FormBuilder,
+              private unitStateService: UnitStateService,
+              @Inject(DOCUMENT) public document: Document) {
   }
 
   ngOnInit(): void {
@@ -31,4 +35,8 @@ export class SectionComponent implements OnInit {
       parentArrayIndex: this.parentArrayIndex
     });
   }
+
+  onIntersection(detection: { detectionType: 'top' | 'bottom' | 'full', id: string }): void {
+    this.unitStateService.changeElementStatus({ id: detection.id, status: 'DISPLAYED' });
+  }
 }
diff --git a/projects/player/src/app/directives/intersection-detection.directive.ts b/projects/player/src/app/directives/intersection-detection.directive.ts
index 77671adbc..0542cc788 100644
--- a/projects/player/src/app/directives/intersection-detection.directive.ts
+++ b/projects/player/src/app/directives/intersection-detection.directive.ts
@@ -6,15 +6,23 @@ import {
   selector: '[appIntersectionDetection]'
 })
 export class IntersectionDetectionDirective implements OnInit, OnDestroy {
-  @Input() detectionType!: 'top' | 'bottom';
-  @Output() intersecting = new EventEmitter<'top' | 'bottom'>();
-  @Input() intersectionContainer!: HTMLElement;
+  @Input() detectionType!: 'top' | 'bottom' | 'full';
+  @Input() id!: string;
+  @Output() intersecting = new EventEmitter<{ detectionType: 'top' | 'bottom' | 'full', id: string }>();
+  @Input() intersectionContainer!: HTMLElement | Document;
 
   intersectionObserver!: IntersectionObserver;
 
+  private constraint!: string;
+
   constructor(private elementRef: ElementRef) {}
 
   ngOnInit(): void {
+    if (this.detectionType === 'top') {
+      this.constraint = '0px 0px -95% 0px';
+    } else {
+      this.constraint = this.detectionType === 'full' ? '0px 0px 0px 0px' : '-95% 0px 0px 0px';
+    }
     this.initIntersectionObserver();
   }
 
@@ -22,11 +30,11 @@ export class IntersectionDetectionDirective implements OnInit, OnDestroy {
     this.intersectionObserver = new IntersectionObserver(
       (entries: IntersectionObserverEntry[]): void => entries.forEach(entry => {
         if (entry.isIntersecting) {
-          this.intersecting.emit(this.detectionType);
+          this.intersecting.emit({ detectionType: this.detectionType, id: this.id });
         }
       }), {
         root: this.intersectionContainer,
-        rootMargin: this.detectionType === 'top' ? '0px 0px -95% 0px' : '-95% 0px 0px 0px'
+        rootMargin: this.constraint
       }
     );
     this.intersectionObserver.observe(this.elementRef.nativeElement);
-- 
GitLab