Mercurial > hg > ugly-duckling
comparison src/app/app.component.ts @ 464:50f61d1945db
Hook up some buttons for navigating history (undo / redo). Some refactoring to allow for the audio player to get updated as a consequence of a state change (the audio related to the current top of the stack is used).
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Fri, 30 Jun 2017 14:01:22 +0100 |
parents | ccce2c09502e |
children | 8820a133bcf5 |
comparison
equal
deleted
inserted
replaced
463:c9c6b01e9b4f | 464:50f61d1945db |
---|---|
17 isPendingAnalysisItem, | 17 isPendingAnalysisItem, |
18 isPendingRootAudioItem, | 18 isPendingRootAudioItem, |
19 isLoadedRootAudioItem, | 19 isLoadedRootAudioItem, |
20 Item, | 20 Item, |
21 RootAudioItem, | 21 RootAudioItem, |
22 LoadedRootAudioItem | 22 getRootAudioItem |
23 } from './analysis-item/AnalysisItem'; | 23 } from './analysis-item/AnalysisItem'; |
24 import {OnSeekHandler} from './playhead/PlayHeadHelpers'; | 24 import {OnSeekHandler} from './playhead/PlayHeadHelpers'; |
25 import {UrlResourceLifetimeManager} from './app.module'; | 25 import {UrlResourceLifetimeManager} from './app.module'; |
26 import {createExtractionRequest} from './analysis-item/AnalysisItem'; | 26 import {createExtractionRequest} from './analysis-item/AnalysisItem'; |
27 import {PersistentStack} from './Session'; | 27 import {PersistentStack} from './Session'; |
36 private onAudioDataSubscription: Subscription; | 36 private onAudioDataSubscription: Subscription; |
37 private onProgressUpdated: Subscription; | 37 private onProgressUpdated: Subscription; |
38 private analyses: PersistentStack<Item>; // TODO some immutable state container describing entire session | 38 private analyses: PersistentStack<Item>; // TODO some immutable state container describing entire session |
39 private nRecordings: number; // TODO user control for naming a recording | 39 private nRecordings: number; // TODO user control for naming a recording |
40 private countingId: number; // TODO improve uniquely identifying items | 40 private countingId: number; // TODO improve uniquely identifying items |
41 private rootAudioItem: LoadedRootAudioItem; | |
42 private onSeek: OnSeekHandler; | 41 private onSeek: OnSeekHandler; |
43 | 42 |
44 constructor(private audioService: AudioPlayerService, | 43 constructor(private audioService: AudioPlayerService, |
45 private featureService: FeatureExtractionService, | 44 private featureService: FeatureExtractionService, |
46 private iconRegistry: MdIconRegistry, | 45 private iconRegistry: MdIconRegistry, |
51 this.analyses = new PersistentStack<AnalysisItem>(); | 50 this.analyses = new PersistentStack<AnalysisItem>(); |
52 this.canExtract = false; | 51 this.canExtract = false; |
53 this.nRecordings = 0; | 52 this.nRecordings = 0; |
54 this.countingId = 0; | 53 this.countingId = 0; |
55 this.onSeek = (time) => this.audioService.seekTo(time); | 54 this.onSeek = (time) => this.audioService.seekTo(time); |
56 this.rootAudioItem = {} as any; // TODO eugh | |
57 | 55 |
58 iconRegistry.addSvgIcon( | 56 iconRegistry.addSvgIcon( |
59 'duck', | 57 'duck', |
60 sanitizer.bypassSecurityTrustResourceUrl('assets/duck.svg') | 58 sanitizer.bypassSecurityTrustResourceUrl('assets/duck.svg') |
61 ); | 59 ); |
65 const wasError = (resource as AudioResourceError).message != null; | 63 const wasError = (resource as AudioResourceError).message != null; |
66 if (wasError) { | 64 if (wasError) { |
67 this.analyses.shift(); | 65 this.analyses.shift(); |
68 this.canExtract = false; | 66 this.canExtract = false; |
69 } else { | 67 } else { |
70 this.rootAudioItem.audioData = (resource as AudioResource).samples; | 68 const audioData = (resource as AudioResource).samples; |
71 if (this.rootAudioItem.audioData) { | 69 if (audioData) { |
70 const rootAudio = getRootAudioItem(this.analyses.get(0)); | |
72 this.canExtract = true; | 71 this.canExtract = true; |
73 const currentRootIndex = this.analyses.findIndex(val => { | 72 const currentRootIndex = this.analyses.findIndex(val => { |
74 return isLoadedRootAudioItem(val) && val.uri === this.rootAudioItem.uri; | 73 return isPendingRootAudioItem(val) && val.uri === rootAudio.uri; |
75 }); | 74 }); |
76 if (currentRootIndex !== -1) { | 75 if (currentRootIndex !== -1) { |
77 this.analyses.set( | 76 this.analyses.set( |
78 currentRootIndex, | 77 currentRootIndex, |
79 Object.assign( | 78 Object.assign( |
80 {}, | 79 {}, |
81 this.analyses.get(currentRootIndex), | 80 this.analyses.get(currentRootIndex), |
82 {audioData: this.rootAudioItem.audioData} | 81 {audioData} |
83 ) | 82 ) |
84 ); | 83 ); |
85 } | 84 } |
86 } | 85 } |
87 } | 86 } |
128 description: new Date().toLocaleString(), | 127 description: new Date().toLocaleString(), |
129 id: `${++this.countingId}`, | 128 id: `${++this.countingId}`, |
130 mimeType: file.type, | 129 mimeType: file.type, |
131 isExportable: createExportableItem | 130 isExportable: createExportableItem |
132 } as RootAudioItem; | 131 } as RootAudioItem; |
133 this.rootAudioItem = pending as LoadedRootAudioItem; // TODO this is silly | |
134 | 132 |
135 // TODO re-ordering of items for display | 133 // TODO re-ordering of items for display |
136 // , one alternative is a Angular Pipe / Filter for use in the Template | 134 // , one alternative is a Angular Pipe / Filter for use in the Template |
137 this.analyses.unshift(pending); | 135 this.analyses.unshift(pending); |
138 } | 136 } |
142 return; | 140 return; |
143 } | 141 } |
144 | 142 |
145 this.canExtract = false; | 143 this.canExtract = false; |
146 | 144 |
147 const placeholderCard: AnalysisItem = { | 145 const rootAudio = getRootAudioItem(this.analyses.get(0)); |
148 parent: this.rootAudioItem, | 146 |
149 hasSharedTimeline: true, | 147 if (isLoadedRootAudioItem(rootAudio)) { |
150 extractorKey: outputInfo.extractorKey, | 148 const placeholderCard: AnalysisItem = { |
151 outputId: outputInfo.outputId, | 149 parent: rootAudio, |
152 title: outputInfo.name, | 150 hasSharedTimeline: true, |
153 description: outputInfo.outputId, | 151 extractorKey: outputInfo.extractorKey, |
154 id: `${++this.countingId}`, | 152 outputId: outputInfo.outputId, |
155 progress: 0 | 153 title: outputInfo.name, |
156 }; | 154 description: outputInfo.outputId, |
157 this.analyses.unshift(placeholderCard); | 155 id: `${++this.countingId}`, |
158 this.sendExtractionRequest(placeholderCard); | 156 progress: 0 |
159 return placeholderCard.id; | 157 }; |
158 this.analyses.unshift(placeholderCard); | |
159 this.sendExtractionRequest(placeholderCard); | |
160 return placeholderCard.id; | |
161 } | |
162 throw new Error('Cannot extract. No audio loaded'); | |
160 } | 163 } |
161 | 164 |
162 removeItem(item: Item): void { | 165 removeItem(item: Item): void { |
163 const indicesToRemove: number[] = this.analyses.reduce( | 166 const indicesToRemove: number[] = this.analyses.reduce( |
164 (toRemove, current, index) => { | 167 (toRemove, current, index) => { |
168 toRemove.push(index); | 171 toRemove.push(index); |
169 } | 172 } |
170 return toRemove; | 173 return toRemove; |
171 }, []); | 174 }, []); |
172 this.analyses.remove(...indicesToRemove); | 175 this.analyses.remove(...indicesToRemove); |
173 if (isPendingRootAudioItem(item)) { | |
174 if (this.rootAudioItem.uri === item.uri) { | |
175 this.audioService.unload(); | |
176 const topItem = this.analyses.get(0); | |
177 const nullRootAudio: LoadedRootAudioItem = {uri: ''} as any; // TODO eugh | |
178 | |
179 if (topItem) { | |
180 if (isPendingAnalysisItem(topItem)) { | |
181 this.rootAudioItem = topItem.parent as LoadedRootAudioItem; | |
182 } else if (isPendingRootAudioItem(topItem)) { | |
183 this.rootAudioItem = topItem as LoadedRootAudioItem; | |
184 } else { | |
185 this.rootAudioItem = nullRootAudio; | |
186 } | |
187 } else { | |
188 this.rootAudioItem = nullRootAudio; | |
189 } | |
190 if (this.rootAudioItem) { | |
191 this.audioService.loadAudioFromUri(this.rootAudioItem.uri); | |
192 } | |
193 } else { | |
194 this.resourceManager.revokeUrlToResource(item.uri); | |
195 } | |
196 } | |
197 } | 176 } |
198 | 177 |
199 ngOnDestroy(): void { | 178 ngOnDestroy(): void { |
200 this.onAudioDataSubscription.unsubscribe(); | 179 this.onAudioDataSubscription.unsubscribe(); |
201 this.onProgressUpdated.unsubscribe(); | 180 this.onProgressUpdated.unsubscribe(); |