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