Mercurial > hg > ugly-duckling
view 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 |
line wrap: on
line source
/** * Created by lucast on 21/03/2017. */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnDestroy, Output } from '@angular/core'; import Waves from 'waves-ui-piper'; import { getRootUri, isLoadedRootAudioItem, Item } from '../analysis-item/AnalysisItem'; import {Observable} from 'rxjs/Observable'; import {Dimension} from '../app.module'; import {Subscription} from 'rxjs/Subscription'; import {OnSeekHandler} from '../playhead/PlayHeadHelpers'; @Component({ selector: 'ugly-notebook-feed', templateUrl: './notebook-feed.component.html', styleUrls: ['./notebook-feed.component.css'], changeDetection: ChangeDetectionStrategy.OnPush }) export class NotebookFeedComponent implements OnDestroy { @Input() analyses: Item[]; @Input() set rootAudioUri(uri: string) { this._rootAudioUri = uri; } @Input() onSeek: OnSeekHandler; @Output() removeItem: EventEmitter<Item>; get rootAudioUri(): string { return this._rootAudioUri; } private _rootAudioUri: string; private resizeSubscription: Subscription; private width: number; private lastWidth: number; private timelines: Map<string, Timeline>; constructor( private ref: ChangeDetectorRef, @Inject('DimensionObservable') private onResize: Observable<Dimension> ) { this.removeItem = new EventEmitter<Item>(); this.timelines = new Map(); this.onResize.subscribe(dim => { this.lastWidth = this.width; this.width = dim.width; }); // the use of requestAnimationFrame here is to leave the dom updates // to a time convenient for the browser, and avoid a cascade / waterfall // of DOM changes for rapid resize events in the event handler above. // ..I'm not convinced this is particularly beneficial here // TODO const triggerChangeDetectionOnResize = () => { requestAnimationFrame(triggerChangeDetectionOnResize); if (this.width !== this.lastWidth) { ref.markForCheck(); // only trigger change detection if width changed } }; requestAnimationFrame(triggerChangeDetectionOnResize); } getOrCreateTimeline(item: Item): Timeline | void { if (!item.hasSharedTimeline) { return; } const uri = getRootUri(item); if (this.timelines.has(uri)) { return this.timelines.get(uri); } else { const timeline = new Waves.core.Timeline(); this.timelines.set(uri, timeline); return timeline; } } isAudioItem(item: Item): boolean { return isLoadedRootAudioItem(item); } isActiveItem(item: Item): boolean { return this.rootAudioUri === getRootUri(item); } getOnSeekForItem(item: Item): (timeSeconds: number) => any { return this.isActiveItem(item) ? this.onSeek : () => {}; } ngOnDestroy(): void { if (this.resizeSubscription) { this.resizeSubscription.unsubscribe(); } } }