dev@170
|
1 /**
|
dev@170
|
2 * Created by lucast on 21/03/2017.
|
dev@170
|
3 */
|
dev@231
|
4 import {
|
dev@231
|
5 ChangeDetectionStrategy,
|
dev@231
|
6 Component,
|
dev@231
|
7 Input,
|
dev@231
|
8 OnInit
|
dev@236
|
9 } from '@angular/core';
|
dev@348
|
10 import {naivePagingMapper} from '../visualisations/WavesJunk';
|
dev@348
|
11 import {OnSeekHandler, TimePixelMapper} from '../playhead/PlayHeadHelpers';
|
dev@361
|
12 import {
|
dev@361
|
13 HigherLevelFeatureShape,
|
dev@361
|
14 KnownShapedFeature
|
dev@361
|
15 } from '../visualisations/FeatureUtilities';
|
dev@170
|
16
|
dev@350
|
17 export interface Item {
|
dev@350
|
18 id: string;
|
dev@200
|
19 hasSharedTimeline: boolean;
|
dev@200
|
20 title?: string;
|
dev@200
|
21 description?: string;
|
dev@224
|
22 progress?: number;
|
dev@350
|
23 }
|
dev@350
|
24
|
dev@350
|
25 export interface PendingRootAudioItem extends Item {
|
dev@350
|
26 uri: string;
|
dev@350
|
27 }
|
dev@378
|
28 export interface RootAudioItem extends PendingRootAudioItem {
|
dev@350
|
29 audioData: AudioBuffer;
|
dev@350
|
30 }
|
dev@350
|
31
|
dev@350
|
32 export interface PendingAnalysisItem extends Item {
|
dev@350
|
33 parent: RootAudioItem;
|
dev@350
|
34 extractorKey: string;
|
dev@350
|
35 }
|
dev@350
|
36
|
dev@361
|
37 export type AnalysisItem = PendingAnalysisItem & KnownShapedFeature;
|
dev@361
|
38
|
dev@361
|
39 export function isItem(item: Item): item is Item {
|
dev@361
|
40 return item.id != null && item.hasSharedTimeline != null;
|
dev@350
|
41 }
|
dev@350
|
42
|
dev@350
|
43 export function isPendingRootAudioItem(item: Item): item is PendingRootAudioItem {
|
dev@361
|
44 return isItem(item) && typeof (item as RootAudioItem).uri === 'string';
|
dev@350
|
45 }
|
dev@350
|
46
|
dev@350
|
47 export function isRootAudioItem(item: Item): item is RootAudioItem {
|
dev@350
|
48 return isPendingRootAudioItem(item) &&
|
dev@351
|
49 (item as RootAudioItem).audioData instanceof AudioBuffer;
|
dev@350
|
50 }
|
dev@350
|
51
|
dev@350
|
52 export function isPendingAnalysisItem(item: Item): item is AnalysisItem {
|
dev@350
|
53 const downcast = (item as AnalysisItem);
|
dev@350
|
54 return isRootAudioItem(downcast.parent)
|
dev@350
|
55 && typeof downcast.extractorKey === 'string';
|
dev@350
|
56 }
|
dev@350
|
57
|
dev@350
|
58 export function isAnalysisItem(item: Item): item is AnalysisItem {
|
dev@350
|
59 const downcast = (item as AnalysisItem);
|
dev@361
|
60 return isPendingAnalysisItem(item) &&
|
dev@361
|
61 downcast.shape != null &&
|
dev@361
|
62 downcast.collected != null;
|
dev@350
|
63 }
|
dev@350
|
64
|
dev@350
|
65 // these should probably be actual concrete types with their own getUri methods
|
dev@350
|
66 export function getRootUri(item: Item): string {
|
dev@350
|
67 if (isPendingRootAudioItem(item)) {
|
dev@350
|
68 return item.uri;
|
dev@350
|
69 }
|
dev@350
|
70 if (isPendingAnalysisItem(item)) {
|
dev@350
|
71 return item.parent.uri;
|
dev@350
|
72 }
|
dev@350
|
73 throw new Error('Invalid item: No URI property set.');
|
dev@170
|
74 }
|
dev@170
|
75
|
dev@170
|
76 @Component({
|
dev@170
|
77 selector: 'ugly-analysis-item',
|
dev@170
|
78 templateUrl: './analysis-item.component.html',
|
dev@231
|
79 styleUrls: ['./analysis-item.component.css'],
|
dev@231
|
80 changeDetection: ChangeDetectionStrategy.OnPush
|
dev@170
|
81 })
|
dev@224
|
82 export class AnalysisItemComponent implements OnInit {
|
dev@224
|
83
|
dev@350
|
84 @Input() timeline: Timeline; // TODO should be TimelineTimeContext?
|
dev@200
|
85 @Input() isActive: boolean;
|
dev@350
|
86 @Input() item: Item;
|
dev@285
|
87 @Input() contentWidth: number;
|
dev@348
|
88 @Input() onSeek: OnSeekHandler;
|
dev@224
|
89 private hasProgressOnInit = false;
|
dev@224
|
90
|
dev@348
|
91
|
dev@348
|
92 // TODO move
|
dev@348
|
93 private DOES_NOT_BELONG_HERE: TimePixelMapper;
|
dev@348
|
94
|
dev@224
|
95 ngOnInit(): void {
|
dev@231
|
96 this.hasProgressOnInit = this.item.progress != null;
|
dev@348
|
97 this.DOES_NOT_BELONG_HERE = naivePagingMapper(this.timeline);
|
dev@224
|
98 }
|
dev@224
|
99
|
dev@224
|
100 isLoading(): boolean {
|
dev@231
|
101 return this.hasProgressOnInit && this.item.progress < 100;
|
dev@224
|
102 }
|
dev@348
|
103
|
dev@348
|
104 isAudioItem(): boolean {
|
dev@350
|
105 return isRootAudioItem(this.item);
|
dev@348
|
106 }
|
dev@361
|
107
|
dev@361
|
108 getFeatureShape(): HigherLevelFeatureShape | null {
|
dev@361
|
109 return !isPendingRootAudioItem(this.item) &&
|
dev@361
|
110 isAnalysisItem(this.item) ? this.item.shape : null;
|
dev@361
|
111 }
|
dev@170
|
112 }
|