annotate src/app/analysis-item/analysis-item.component.ts @ 381:b220ed78a250

Rig up instants and add dynamic colour selection to feature components. Structure of a derived WaveComponent is now pretty clear, some refactoring is in order.
author Lucas Thompson <dev@lucas.im>
date Wed, 31 May 2017 17:09:36 +0100
parents 9fe6e00e0700
children 3eab26a629e1
rev   line source
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 }