annotate src/app/notebook-feed/notebook-feed.component.ts @ 456:7bb0bac6f8dc

Add export button for recordings and option to remove audio item (also removes all related analyses atm). Revokes associated object url for audio on removal. Will be problematic if the history is used for undo / redo.
author Lucas Thompson <dev@lucas.im>
date Thu, 29 Jun 2017 20:11:14 +0100
parents 524f5cd75737
children ccce2c09502e
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@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@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@350 85 return isRootAudioItem(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 }