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