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@232
|
7 Component,
|
dev@285
|
8 Inject,
|
dev@285
|
9 Input,
|
dev@285
|
10 OnDestroy
|
dev@236
|
11 } from '@angular/core';
|
dev@289
|
12 import Waves from 'waves-ui-piper';
|
dev@350
|
13 import {
|
dev@350
|
14 getRootUri,
|
dev@350
|
15 isRootAudioItem,
|
dev@350
|
16 Item
|
dev@350
|
17 } from '../analysis-item/analysis-item.component';
|
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@171
|
35
|
dev@201
|
36 get rootAudioUri(): string {
|
dev@201
|
37 return this._rootAudioUri;
|
dev@171
|
38 }
|
dev@201
|
39 private _rootAudioUri: string;
|
dev@285
|
40 private resizeSubscription: Subscription;
|
dev@285
|
41 private width: number;
|
dev@285
|
42 private lastWidth: number;
|
dev@282
|
43 private timelines: Map<string, Timeline>;
|
dev@181
|
44
|
dev@285
|
45 constructor(
|
dev@285
|
46 private ref: ChangeDetectorRef,
|
dev@285
|
47 @Inject('DimensionObservable') private onResize: Observable<Dimension>
|
dev@285
|
48 ) {
|
dev@282
|
49 this.timelines = new Map();
|
dev@285
|
50 this.onResize.subscribe(dim => {
|
dev@285
|
51 this.lastWidth = this.width;
|
dev@285
|
52 this.width = dim.width;
|
dev@285
|
53 });
|
dev@285
|
54
|
dev@285
|
55 // the use of requestAnimationFrame here is to leave the dom updates
|
dev@285
|
56 // to a time convenient for the browser, and avoid a cascade / waterfall
|
dev@285
|
57 // of DOM changes for rapid resize events in the event handler above.
|
dev@285
|
58 // ..I'm not convinced this is particularly beneficial here // TODO
|
dev@285
|
59 const triggerChangeDetectionOnResize = () => {
|
dev@285
|
60 requestAnimationFrame(triggerChangeDetectionOnResize);
|
dev@285
|
61 if (this.width !== this.lastWidth) {
|
dev@285
|
62 ref.markForCheck(); // only trigger change detection if width changed
|
dev@285
|
63 }
|
dev@285
|
64 };
|
dev@285
|
65 requestAnimationFrame(triggerChangeDetectionOnResize);
|
dev@282
|
66 }
|
dev@282
|
67
|
dev@350
|
68 getOrCreateTimeline(item: Item): Timeline | void {
|
dev@282
|
69 if (!item.hasSharedTimeline) {
|
dev@282
|
70 return;
|
dev@282
|
71 }
|
dev@350
|
72 const uri = getRootUri(item);
|
dev@350
|
73 if (this.timelines.has(uri)) {
|
dev@350
|
74 return this.timelines.get(uri);
|
dev@282
|
75 } else {
|
dev@282
|
76 const timeline = new Waves.core.Timeline();
|
dev@350
|
77 this.timelines.set(uri, timeline);
|
dev@282
|
78 return timeline;
|
dev@282
|
79 }
|
dev@181
|
80 }
|
dev@285
|
81
|
dev@350
|
82 isAudioItem(item: Item): boolean {
|
dev@350
|
83 return isRootAudioItem(item);
|
dev@348
|
84 }
|
dev@348
|
85
|
dev@350
|
86 isActiveItem(item: Item): boolean {
|
dev@350
|
87 return this.rootAudioUri === getRootUri(item);
|
dev@350
|
88 }
|
dev@350
|
89
|
dev@350
|
90 getOnSeekForItem(item: Item): (timeSeconds: number) => any {
|
dev@348
|
91 return this.isActiveItem(item) ? this.onSeek : () => {};
|
dev@348
|
92 }
|
dev@348
|
93
|
dev@285
|
94 ngOnDestroy(): void {
|
dev@285
|
95 if (this.resizeSubscription) {
|
dev@285
|
96 this.resizeSubscription.unsubscribe();
|
dev@285
|
97 }
|
dev@285
|
98 }
|
dev@171
|
99 }
|