changeset 235:76f2cd2c5a68

Refactor the root component to push the app state down to children. Currently using an ad-hoc container with similar interface as array used previously. not thought out.
author Lucas Thompson <dev@lucas.im>
date Mon, 24 Apr 2017 17:05:12 +0100
parents 0833ddde6a83
children 53ea6406d601 eedac4a56fe5
files src/app/app.component.html src/app/app.component.ts
diffstat 2 files changed, 63 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/app.component.html	Mon Apr 24 17:03:45 2017 +0100
+++ b/src/app/app.component.html	Mon Apr 24 17:05:12 2017 +0100
@@ -33,19 +33,8 @@
         </app-feature-extraction-menu>
       </md-sidenav>
       <ugly-notebook-feed
-        [analyses]="analyses"
+        [analyses]="analyses.toIterable()"
         [rootAudioUri]="rootAudioUri"></ugly-notebook-feed>
     </md-sidenav-container>
   </div>
-
-  <div class="app-footer">
-    <md-toolbar color="primary">
-
-      <!-- menu opens when trigger button is clicked -->
-      <button md-icon-button (click)="sidenav.toggle()">
-        <md-icon>extension</md-icon>
-      </button>
-    </md-toolbar>
-
-  </div>
 </div>
--- a/src/app/app.component.ts	Mon Apr 24 17:03:45 2017 +0100
+++ b/src/app/app.component.ts	Mon Apr 24 17:05:12 2017 +0100
@@ -10,6 +10,57 @@
 import {Subscription} from "rxjs";
 import {AnalysisItem} from "./analysis-item/analysis-item.component";
 
+class PersistentStack<T> {
+  private stack: T[];
+  private history: T[][];
+
+  constructor() {
+    this.stack = [];
+    this.history = [];
+  }
+
+  shift(): T {
+    this.history.push([...this.stack]);
+    const item = this.stack[0];
+    this.stack = this.stack.slice(1);
+    return item;
+  }
+
+  unshift(item: T): number
+  {
+    this.history.push([...this.stack]);
+    this.stack = [item, ...this.stack];
+    return this.stack.length;
+  }
+
+  findIndex(predicate: (value: T,
+                        index: number,
+                        array: T[]) => boolean): number {
+    return this.stack.findIndex(predicate);
+  }
+
+  filter(predicate: (value: T, index: number, array: T[]) => boolean): T[] {
+    return this.stack.filter(predicate);
+  }
+
+  get(index: number): T {
+    return this.stack[index];
+  }
+
+  set(index: number, value: T) {
+    this.history.push([...this.stack]);
+    this.stack = [
+      ...this.stack.slice(0, index),
+      value,
+      ...this.stack.slice(index + 1)
+    ];
+  }
+
+  toIterable(): Iterable<T> {
+    return this.stack;
+  }
+}
+
 @Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
@@ -20,7 +71,7 @@
   canExtract: boolean;
   private onAudioDataSubscription: Subscription;
   private onProgressUpdated: Subscription;
-  private analyses: AnalysisItem[]; // TODO some immutable state container describing entire session
+  private analyses: PersistentStack<AnalysisItem>; // TODO some immutable state container describing entire session
   private nRecordings: number; // TODO user control for naming a recording
   private countingId: number; // TODO improve uniquely identifying items
   private rootAudioUri: string;
@@ -29,7 +80,7 @@
               private featureService: FeatureExtractionService,
               private iconRegistry: MdIconRegistry,
               private sanitizer: DomSanitizer) {
-    this.analyses = [];
+    this.analyses = new PersistentStack<AnalysisItem>();
     this.canExtract = false;
     this.nRecordings = 0;
     this.countingId = 0;
@@ -57,7 +108,15 @@
       progress => {
         const index = this.analyses.findIndex(val => val.id === progress.id);
         if (index === -1) return;
-        this.analyses[index].progress = progress.value;
+
+        this.analyses.set(
+          index,
+          Object.assign(
+            {},
+            this.analyses.get(index),
+            {progress: progress.value}
+          )
+        );
       }
     );
   }