annotate src/app/notebook-feed/notebook-feed.component.ts @ 460:ccce2c09502e

Manually cherry-pick various refactoring efforts from feature/basic-session-loading
author Lucas Thompson <dev@lucas.im>
date Fri, 30 Jun 2017 10:41:30 +0100
parents 7bb0bac6f8dc
children 50f61d1945db
rev   line source
dev@171 1 /**
dev@171 2 * Created by lucast on 21/03/2017.
dev@171 3 */
dev@232 4 import {
dev@232 5 ChangeDetectionStrategy,
dev@285 6 ChangeDetectorRef,
dev@456 7 Component, EventEmitter,
dev@285 8 Inject,
dev@285 9 Input,
dev@456 10 OnDestroy, Output
dev@236 11 } from '@angular/core';
dev@289 12 import Waves from 'waves-ui-piper';
dev@350 13 import {
dev@350 14 getRootUri,
dev@460 15 isLoadedRootAudioItem,
dev@350 16 Item
dev@460 17 } from '../analysis-item/AnalysisItem';
dev@285 18 import {Observable} from 'rxjs/Observable';
dev@285 19 import {Dimension} from '../app.module';
dev@285 20 import {Subscription} from 'rxjs/Subscription';
dev@348 21 import {OnSeekHandler} from '../playhead/PlayHeadHelpers';
dev@171 22
dev@171 23 @Component({
dev@171 24 selector: 'ugly-notebook-feed',
dev@171 25 templateUrl: './notebook-feed.component.html',
dev@232 26 styleUrls: ['./notebook-feed.component.css'],
dev@232 27 changeDetection: ChangeDetectionStrategy.OnPush
dev@171 28 })
dev@285 29 export class NotebookFeedComponent implements OnDestroy {
dev@350 30 @Input() analyses: Item[];
dev@201 31 @Input() set rootAudioUri(uri: string) {
dev@201 32 this._rootAudioUri = uri;
dev@171 33 }
dev@348 34 @Input() onSeek: OnSeekHandler;
dev@456 35 @Output() removeItem: EventEmitter<Item>;
dev@171 36
dev@201 37 get rootAudioUri(): string {
dev@201 38 return this._rootAudioUri;
dev@171 39 }
dev@201 40 private _rootAudioUri: string;
dev@285 41 private resizeSubscription: Subscription;
dev@285 42 private width: number;
dev@285 43 private lastWidth: number;
dev@282 44 private timelines: Map<string, Timeline>;
dev@181 45
dev@285 46 constructor(
dev@285 47 private ref: ChangeDetectorRef,
dev@285 48 @Inject('DimensionObservable') private onResize: Observable<Dimension>
dev@285 49 ) {
dev@456 50 this.removeItem = new EventEmitter<Item>();
dev@282 51 this.timelines = new Map();
dev@285 52 this.onResize.subscribe(dim => {
dev@285 53 this.lastWidth = this.width;
dev@285 54 this.width = dim.width;
dev@285 55 });
dev@285 56
dev@285 57 // the use of requestAnimationFrame here is to leave the dom updates
dev@285 58 // to a time convenient for the browser, and avoid a cascade / waterfall
dev@285 59 // of DOM changes for rapid resize events in the event handler above.
dev@285 60 // ..I'm not convinced this is particularly beneficial here // TODO
dev@285 61 const triggerChangeDetectionOnResize = () => {
dev@285 62 requestAnimationFrame(triggerChangeDetectionOnResize);
dev@285 63 if (this.width !== this.lastWidth) {
dev@285 64 ref.markForCheck(); // only trigger change detection if width changed
dev@285 65 }
dev@285 66 };
dev@285 67 requestAnimationFrame(triggerChangeDetectionOnResize);
dev@282 68 }
dev@282 69
dev@350 70 getOrCreateTimeline(item: Item): Timeline | void {
dev@282 71 if (!item.hasSharedTimeline) {
dev@282 72 return;
dev@282 73 }
dev@350 74 const uri = getRootUri(item);
dev@350 75 if (this.timelines.has(uri)) {
dev@350 76 return this.timelines.get(uri);
dev@282 77 } else {
dev@282 78 const timeline = new Waves.core.Timeline();
dev@350 79 this.timelines.set(uri, timeline);
dev@282 80 return timeline;
dev@282 81 }
dev@181 82 }
dev@285 83
dev@350 84 isAudioItem(item: Item): boolean {
dev@460 85 return isLoadedRootAudioItem(item);
dev@348 86 }
dev@348 87
dev@350 88 isActiveItem(item: Item): boolean {
dev@350 89 return this.rootAudioUri === getRootUri(item);
dev@350 90 }
dev@350 91
dev@350 92 getOnSeekForItem(item: Item): (timeSeconds: number) => any {
dev@348 93 return this.isActiveItem(item) ? this.onSeek : () => {};
dev@348 94 }
dev@348 95
dev@285 96 ngOnDestroy(): void {
dev@285 97 if (this.resizeSubscription) {
dev@285 98 this.resizeSubscription.unsubscribe();
dev@285 99 }
dev@285 100 }
dev@171 101 }