diff --git a/projects/player/src/app/components/layout/layout.component.html b/projects/player/src/app/components/layout/layout.component.html index 6ac2ab4eb6a285647e5b0562b469bb02d804a40f..66105537eabc3d040fc48195fe03346c7aa6c804 100644 --- a/projects/player/src/app/components/layout/layout.component.html +++ b/projects/player/src/app/components/layout/layout.component.html @@ -19,9 +19,11 @@ [hideFirstChild]="hidePageLabels" [style.max-width.px]="alwaysVisiblePage.width" [style.margin.px]="alwaysVisiblePage.margin"> - <div class="mat-tab-label">{{'alwaysVisiblePage' | translate}}</div> + <div class="mat-tab-label">{{'alwaysVisiblePage' | translate}} {{selectedIndex}}</div> <app-page [parentArrayIndex]="alwaysVisibleUnitPageIndex" + [index]="playerPageIndices[alwaysVisibleUnitPageIndex]" [parentForm]="parentForm" + [isLastPage]="false" [pagesContainer]="alwaysVisiblePageContainer" [page]="alwaysVisiblePage"> </app-page> @@ -51,7 +53,9 @@ label="{{'pageIndication' | translate: {index: playerPageIndices[i] + 1} }}"> <div [style.margin.px]="page.margin" [style.max-width.px]="page.width"> <app-page [parentArrayIndex]="i" + [index]="playerPageIndices[i]" [parentForm]="parentForm" + [isLastPage]="i === lastScrollPageIndex" [pagesContainer]="pagesSeparatedContainer" [page]="page"> </app-page> @@ -74,7 +78,8 @@ appHideFirstChild [hideFirstChild]="hidePageLabels" appScrollIndex - [selectedIndex]="selectedIndex" + [pagesContainer]="pagesScrolledContainer" + [selectIndex]="selectIndex" [index]="playerPageIndices[i]" [style.max-width.px]="page.width" [style.margin.px]="page.margin"> @@ -82,9 +87,11 @@ {{'pageIndication' | translate: {index: playerPageIndices[i] + 1} }} </div> <app-page [parentArrayIndex]="i" + [index]="playerPageIndices[i]" [parentForm]="parentForm" [pagesContainer]="pagesScrolledContainer" [page]="page" + [isLastPage]="i === lastScrollPageIndex" (selectedIndexChange)="onSelectedIndexChange($event)"> </app-page> </div> diff --git a/projects/player/src/app/components/layout/layout.component.ts b/projects/player/src/app/components/layout/layout.component.ts index 833c1e9bee19f9955d2789b3c2e1629106fe5a49..95abd6d644a678c6760f712b009f0e6e39fa9bad 100644 --- a/projects/player/src/app/components/layout/layout.component.ts +++ b/projects/player/src/app/components/layout/layout.component.ts @@ -3,6 +3,7 @@ import { } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; +import { Subject } from 'rxjs'; import { UnitPage } from '../../../../../common/unit'; import { PlayerConfig } from '../../models/verona'; @@ -15,18 +16,18 @@ export class LayoutComponent implements OnInit { @Input() parentForm!: FormGroup; @Input() pages!: UnitPage[]; @Input() selectedIndex!: number; + @Input() selectIndex!: Subject<number>; @Input() playerConfig!: PlayerConfig; @Output() selectedIndexChange = new EventEmitter<number>(); @Output() validPagesDetermined = new EventEmitter<Record<string, string>[]>(); playerPageIndices!: number[]; + lastScrollPageIndex!: number; scrollPages!: UnitPage[]; hasScrollPages!: boolean; alwaysVisiblePage!: UnitPage | undefined; alwaysVisibleUnitPageIndex!: number; - - pageExpansion!: number; alwaysVisiblePagePosition!: 'top' | 'bottom' | 'left' | 'right' ; layoutAlignment!: 'row' | 'column'; scrollPageMode!: 'separate' | 'concat-scroll' | 'concat-scroll-snap'; @@ -40,6 +41,14 @@ export class LayoutComponent implements OnInit { ngOnInit(): void { this.initPages(); this.initLayout(); + this.selectIndex.subscribe((selectedIndex: number): void => { this.selectedIndex = selectedIndex; }); + } + + private getLastScrollPageIndex(): number { + if (this.alwaysVisibleUnitPageIndex < 0 || this.alwaysVisibleUnitPageIndex < this.pages.length - 1) { + return this.pages.length - 1; + } + return this.pages.length - 2; } private initPages(): void { @@ -47,6 +56,7 @@ export class LayoutComponent implements OnInit { this.alwaysVisiblePage = this.pages[this.alwaysVisibleUnitPageIndex]; this.scrollPages = this.pages.filter((page: UnitPage): boolean => !page.alwaysVisible); this.hasScrollPages = this.scrollPages && this.scrollPages.length > 0; + this.lastScrollPageIndex = this.getLastScrollPageIndex(); this.playerPageIndices = this.pages.map( (page: UnitPage, index: number): number => { if (index === this.alwaysVisibleUnitPageIndex) { @@ -56,7 +66,7 @@ export class LayoutComponent implements OnInit { } ); this.validPagesDetermined.emit(this.scrollPages.map((page: UnitPage, index: number): Record<string, string> => ( - { [page.id]: `${this.translateService.instant('pageIndication', { index: index + 1 })}` }))); + { [index]: `${this.translateService.instant('pageIndication', { index: index + 1 })}` }))); } private initLayout(): void { @@ -64,13 +74,10 @@ export class LayoutComponent implements OnInit { this.alwaysVisiblePage.alwaysVisiblePagePosition : 'left'; this.layoutAlignment = (this.alwaysVisiblePagePosition === 'left' || this.alwaysVisiblePagePosition === 'right') ? 'row' : 'column'; - this.pageExpansion = !this.alwaysVisiblePage || !this.hasScrollPages ? 100 : 50; this.scrollPageMode = this.playerConfig.pagingMode ? this.playerConfig.pagingMode : 'separate'; this.hidePageLabels = false; - this.alwaysVisiblePageWidth = this.getAbsolutePageWidth(this.alwaysVisiblePage); this.scrollPageWidth = this.calculateScrollPagesWidth(); - this.layoutWidth = this.layoutAlignment === 'row' ? this.alwaysVisiblePageWidth + this.scrollPageWidth : Math.max(this.alwaysVisiblePageWidth, this.scrollPageWidth); } diff --git a/projects/player/src/app/components/page/page.component.html b/projects/player/src/app/components/page/page.component.html index 23c4f7a016109851febcbe7c1c2e6a369042eae0..0f635175115fb29fe7f36da59b613806927ef422 100644 --- a/projects/player/src/app/components/page/page.component.html +++ b/projects/player/src/app/components/page/page.component.html @@ -1,20 +1,20 @@ <div appIntersectionDetection detectionType="top" [intersectionContainer]="pagesContainer" - (intersecting)="onIntersection($event)" -></div> -<app-section *ngFor="let section of page.sections; let i = index; let last = last" - [parentForm]="pageForm" - [parentArrayIndex]="i" - [section]="section" - [ngStyle]="{ - position: 'relative', - display: 'block', - overflow: 'auto', - width: '100%', - 'background-color': section.backgroundColor, - 'min-height.px': section.height}"> -</app-section> + (intersecting)="onIntersection($event)"> + <app-section *ngFor="let section of page.sections; let i = index" + [parentForm]="pageForm" + [parentArrayIndex]="i" + [section]="section" + [ngStyle]="{ + position: 'relative', + display: 'block', + overflow: 'auto', + width: '100%', + 'background-color': section.backgroundColor, + 'min-height.px': section.height}"> + </app-section> +</div> <div appIntersectionDetection detectionType="bottom" [intersectionContainer]="pagesContainer" diff --git a/projects/player/src/app/components/page/page.component.ts b/projects/player/src/app/components/page/page.component.ts index 6890b1f49b3d5573559172eb797512945e362a9c..02ee57006ea8ab1a162c032cb5d213acbccd490a 100644 --- a/projects/player/src/app/components/page/page.component.ts +++ b/projects/player/src/app/components/page/page.component.ts @@ -12,8 +12,10 @@ import { FormService } from '../../../../../common/form.service'; export class PageComponent implements OnInit { @Input() page!: UnitPage; + @Input() isLastPage!: boolean; @Input() parentForm!: FormGroup; @Input() parentArrayIndex!: number; + @Input() index!: number; @Input() pagesContainer!: HTMLElement; @Output() selectedIndexChange = new EventEmitter<number>(); pageForm!: FormGroup; @@ -36,10 +38,10 @@ export class PageComponent implements OnInit { onIntersection(detectionType: 'top' | 'bottom'): void { if (detectionType === 'bottom') { - this.formService.addPresentedPage(this.parentArrayIndex); + this.formService.addPresentedPage(this.index); } - if (detectionType === 'top') { - this.selectedIndexChange.emit(this.parentArrayIndex); + if (detectionType === 'top' || this.isLastPage) { + this.selectedIndexChange.emit(this.index); } } } diff --git a/projects/player/src/app/components/player-state/player-state.component.html b/projects/player/src/app/components/player-state/player-state.component.html index a50e60bebca49fd2a02ade0d61edadeb3a5a12cb..9335b5f92c052718f508e622d02a15a62887cfd5 100644 --- a/projects/player/src/app/components/player-state/player-state.component.html +++ b/projects/player/src/app/components/player-state/player-state.component.html @@ -3,6 +3,7 @@ [pages]="pages" [playerConfig]="playerConfig" [(selectedIndex)]="currentPlayerPageIndex" + [selectIndex]="selectIndex" (validPagesDetermined)="onValidPagesDetermined($event)" (selectedIndexChange)="onSelectedIndexChange()"> </app-layout> diff --git a/projects/player/src/app/components/player-state/player-state.component.ts b/projects/player/src/app/components/player-state/player-state.component.ts index 75b18e4f55b8c6c085d47bb887633e9777219b26..34844c14536609c8772be2bd0beb92627df727bb 100644 --- a/projects/player/src/app/components/player-state/player-state.component.ts +++ b/projects/player/src/app/components/player-state/player-state.component.ts @@ -23,6 +23,7 @@ export class PlayerStateComponent implements OnInit, OnDestroy { @Input() playerConfig!: PlayerConfig; currentPlayerPageIndex: number = 0; + selectIndex: Subject<number> = new Subject(); running: boolean = true; validPages!: Record<string, string> []; @@ -90,7 +91,7 @@ export class PlayerStateComponent implements OnInit, OnDestroy { private onPageNavigation(message: VopPageNavigationCommand): void { // eslint-disable-next-line no-console console.log('player: onPageNavigation', message); - this.currentPlayerPageIndex = parseInt(message.target, 10); + this.selectIndex.next(parseInt(message.target, 10)); } private sendVopStateChangedNotification(): void { diff --git a/projects/player/src/app/directives/intersection-detection.directive.ts b/projects/player/src/app/directives/intersection-detection.directive.ts index 0861c1ee5bbe510a0f7466a4206060cd0b7ba536..77671adbc873c353b1ed696781146add777a0d17 100644 --- a/projects/player/src/app/directives/intersection-detection.directive.ts +++ b/projects/player/src/app/directives/intersection-detection.directive.ts @@ -26,7 +26,7 @@ export class IntersectionDetectionDirective implements OnInit, OnDestroy { } }), { root: this.intersectionContainer, - rootMargin: this.detectionType === 'top' ? '0% 0px -95% 0px' : '0px 0px 0px 0px' + rootMargin: this.detectionType === 'top' ? '0px 0px -95% 0px' : '-95% 0px 0px 0px' } ); this.intersectionObserver.observe(this.elementRef.nativeElement); diff --git a/projects/player/src/app/directives/scroll-index.directive.ts b/projects/player/src/app/directives/scroll-index.directive.ts index bc21f3a3b79c4dc70b6cb3d6ce7cc19b60f6e2fc..f5606098e3b93d137537118cbc2671eb411aedf0 100644 --- a/projects/player/src/app/directives/scroll-index.directive.ts +++ b/projects/player/src/app/directives/scroll-index.directive.ts @@ -1,20 +1,23 @@ import { - Directive, ElementRef, Input, OnChanges, SimpleChanges + Directive, ElementRef, Input, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; @Directive({ selector: '[appScrollIndex]' }) -export class ScrollIndexDirective implements OnChanges { - @Input() selectedIndex!: number; +export class ScrollIndexDirective implements OnInit { + @Input() selectIndex!: Subject<number>; @Input() index!: number; + @Input() pagesContainer!: HTMLElement; - constructor(private elementRef: ElementRef) { - } + constructor(private elementRef: ElementRef) {} - ngOnChanges(changes: SimpleChanges): void { - if (changes.selectedIndex?.currentValue === this.index) { - this.elementRef.nativeElement.scrollIntoView({ behavior: 'smooth' }); - } + ngOnInit(): void { + this.selectIndex.subscribe((selectedIndex: number): void => { + if (selectedIndex === this.index) { + this.elementRef.nativeElement.scrollIntoView({ behavior: 'smooth' }); + } + }); } } diff --git a/projects/player/src/index.html b/projects/player/src/index.html index 00d1f29322eecd1acd3b56040b666084733e76c6..d11571072ec08d7374507ac30938e54f05704dd8 100644 --- a/projects/player/src/index.html +++ b/projects/player/src/index.html @@ -29,9 +29,10 @@ </fieldset> </form> <button onclick='denyNavigation();'>Deny Navigation</button> - <button onclick='toPage(0);'>Page 1</button> - <button onclick='toPage(1);'>Page 2</button> - <button onclick='toPage(2);'>Page 3</button> + <button onclick='toPage(0);'>1</button> + <button onclick='toPage(1);'>2</button> + <button onclick='toPage(2);'>3</button> + <button onclick='toPage(3);'>4</button> </div> </body>