From 502981833ef7f9e8179bf9c487b1e35404c6d4e1 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 28 Jul 2020 15:08:56 -0700
Subject: fix recursion bug and make link turn blue

---
 .../views/nodes/formattedText/FormattedTextBox.tsx | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 6b6fc5da2..b1d9be73b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1295,6 +1295,30 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         }
         e.stopPropagation();
         if (e.key === "Tab" || e.key === "Enter") {
+            // console.log(this._recording);
+            // if (this._editorView) {
+            //     const state = this._editorView.state;
+            //     const now = Date.now();
+            //     let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
+            //     if (!this._break && state.selection.to !== state.selection.from) {
+            //         for (let i = state.selection.from; i <= state.selection.to; i++) {
+            //             const pos = state.doc.resolve(i);
+            //             const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark);
+            //             if (um) {
+            //                 mark = um;
+            //                 break;
+            //             }
+            //         }
+            //     }
+            //     const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime();
+            //     this._break = false;
+            //     let value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000;
+            //     //let value = "[0:02]";
+            //     const from = state.selection.from;
+            //     const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
+
+            //     this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1)));
+            // }
             e.preventDefault();
         }
         if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) {
-- 
cgit v1.2.3-70-g09d2


From e25afb5fe507ff13cb6e863c07032d9d9dcc864b Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Mon, 3 Aug 2020 12:37:32 -0700
Subject: added timestamps and added delete for markers and changed the way
 markers are rendered

---
 src/client/documents/Documents.ts                  |   2 +-
 src/client/views/nodes/AudioBox.scss               |   1 +
 src/client/views/nodes/AudioBox.tsx                | 113 ++++++++++++-------
 .../views/nodes/formattedText/FormattedTextBox.tsx | 124 ++++++++++++++++-----
 4 files changed, 172 insertions(+), 68 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 88f470576..402f3e82c 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -628,7 +628,7 @@ export namespace Docs {
         }
 
         export function AudioDocument(url: string, options: DocumentOptions = {}) {
-            const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { ...options }); // hideLinkButton: false, useLinkSmallAnchor: false,
+            const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { useLinkSmallAnchor: true, ...options }); // hideLinkButton: false, useLinkSmallAnchor: false,
             Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'");
             return instance;
         }
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 35ab5da8b..0ea4b37cb 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -148,6 +148,7 @@
                     width: 100%;
                     height: 100%;
                     overflow: hidden;
+                    z-index: 0;
                 }
 
                 .audiobox-linker,
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 3d1932883..7c90547ef 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -75,6 +75,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _markers: Array<any> = [];
     _first: boolean = false;
     _buckets: Array<number> = new Array();
+    _count: Array<any> = [];
 
     private _isPointerDown = false;
     private _currMarker: any;
@@ -516,53 +517,74 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return false;
     }
 
+    markers = () => {
+        const increment = NumCast(this.layoutDoc.duration) / 500;
+        this._count = [];
+        for (let i = 0; i < 500; i++) {
+            this._count.push([increment * i, 0])
+        }
+
+    }
+
     // Probably need a better way to format
-    isOverlap = (m: any, i: number) => {
-        console.log("called");
-        let counter = 0;
+    // isOverlap = (m: any, i: number) => {
+    //     console.log("called");
+    //     let counter = 0;
 
+    //     if (this._first) {
+    //         this._markers = [];
+    //         this._first = false;
+    //     }
+    //     for (let i = 0; i < this._markers.length; i++) {
+    //         if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) {
+    //             counter++;
+    //             console.log(counter);
+    //         }
+    //     }
+
+    //     if (this.dataDoc.markerAmount < counter) {
+    //         this.dataDoc.markerAmount = counter;
+    //     }
+
+    //     this._markers.push(m);
+
+    //     return counter;
+    // }
+
+    isOverlap = (m: any) => {
         if (this._first) {
-            this._markers = [];
             this._first = false;
-        }
-        for (let i = 0; i < this._markers.length; i++) {
-            if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) {
-                counter++;
-                console.log(counter);
-            }
+            this.markers();
+            console.log(this._count);
         }
 
-        if (this.dataDoc.markerAmount < counter) {
-            this.dataDoc.markerAmount = counter;
-        }
 
-        this._markers.push(m);
+        let max = 0
 
-        return counter;
-    }
+        for (let i = 0; i < 500; i++) {
+            if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) {
+                this._count[i][1]++;
 
-    // isOverlap = (m: any) => {
-    //     if (this._markers.length < 1) {
-    //         this._markers = new Array(Math.round(this.dataDoc.duration)).fill(0);
-    //     }
-    //     console.log(this._markers);
-    //     let max = 0
+                if (this._count[i][1] > max) {
+                    max = this._count[i][1];
+                }
+            }
 
-    //     for (let i = Math.round(m.audioStart); i <= Math.round(m.audioEnd); i++) {
-    //         this._markers[i] = this._markers[i] + 1;
-    //         console.log(this._markers[i]);
 
-    //         if (this._markers[i] > max) {
-    //             max = this._markers[i];
-    //         }
-    //     }
+        }
 
-    //     console.log(max);
-    //     if (this.dataDoc.markerAmount < max) {
-    //         this.dataDoc.markerAmount = max;
-    //     }
-    //     return max
-    // }
+        for (let i = 0; i < 500; i++) {
+            if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) {
+                this._count[i][1] = max;
+            }
+
+        }
+
+        if (this.dataDoc.markerAmount < max) {
+            this.dataDoc.markerAmount = max;
+        }
+        return max - 1
+    }
 
     formatTime = (time: number) => {
         const hours = Math.floor(time / 60 / 60);
@@ -609,6 +631,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._first = true;
     }
 
+    @computed get height() {
+        console.log(this.layoutDoc._height);
+        if (this.layoutDoc._height) {
+            return 0.8 * this.layoutDoc._height
+        }
+    }
+
     render() {
         //trace();
         const interactive = this.active() ? "-interactive" : "";
@@ -673,14 +702,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     this._hold ? this.end(this._ele!.currentTime) : this.start(this._ele!.currentTime);
                                 }
                             }}>
-                            <div className="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
+                            <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
                                 {console.log(this.peaks)}
                                 <Waveform
                                     color={"#000000"}
-                                    height={20}
+                                    height={this.height}
                                     barWidth={0.1}
                                     pos={this.layoutDoc.currentTimecode}
-                                    duration={this.layoutDoc.duration}
+                                    duration={this.dataDoc.duration}
                                     peaks={this._buckets.length === 100 ? this._buckets : undefined}
                                     progressColor={"#0000ff"} />
                             </div>
@@ -690,7 +719,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 (!m.isLabel) ?
                                     (this.layoutDoc.hideMarkers) ? (null) :
                                         rect =
-                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${this.formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${this.formatTime(Math.round(NumCast(m.audioEnd)))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 2) * 100}%`, top: `${this.isOverlap(m, i) * 1 / (this.dataDoc.markerAmount + 2) * 100}%` }} onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} >
+                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${this.formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${this.formatTime(Math.round(NumCast(m.audioEnd)))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`, top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%` }} onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} >
                                             <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
                                             <DocumentView {...this.props}
                                                 Document={m}
@@ -700,7 +729,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                                 rootSelected={returnFalse}
                                                 LayoutTemplate={undefined}
                                                 ContainingCollectionDoc={this.props.Document}
-                                                removeDocument={undefined}
+                                                removeDocument={this.removeDocument}
                                                 parentActive={returnTrue}
                                                 onClick={this.layoutDoc.playOnClick ? this.rangeScript : undefined}
                                                 ignoreAutoHeight={false}
@@ -722,7 +751,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                                 rootSelected={returnFalse}
                                                 LayoutTemplate={undefined}
                                                 ContainingCollectionDoc={this.props.Document}
-                                                removeDocument={undefined}
+                                                removeDocument={this.removeDocument}
                                                 parentActive={returnTrue}
                                                 onClick={this.layoutDoc.playOnClick ? this.labelScript : undefined}
                                                 ignoreAutoHeight={false}
@@ -776,7 +805,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
                         </div>
                         <div className="total-time">
-                            {this.formatTime(Math.round(NumCast(this.layoutDoc.duration)))}
+                            {this.formatTime(Math.round(NumCast(this.dataDoc.duration)))}
                         </div>
                     </div>
                 </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b1d9be73b..91940466f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -2,7 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core';
 import { faEdit, faSmile, faTextHeight, faUpload } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { isEqual } from "lodash";
-import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { baseKeymap, selectAll } from "prosemirror-commands";
 import { history } from "prosemirror-history";
@@ -93,6 +93,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     private _undoTyping?: UndoManager.Batch;
     private _disposers: { [name: string]: IReactionDisposer } = {};
     private _dropDisposer?: DragManager.DragDropDisposer;
+    private _first: Boolean = true;
+    private _recordingStart: number = 0;
+    private _currentTime: number = 0;
+    private _linkTime: number | null = null;
+    private _pause: boolean = false;
 
     @computed get _recording() { return this.dataDoc.audioState === "recording"; }
     set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; }
@@ -140,6 +145,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         super(props);
         FormattedTextBox.Instance = this;
         this.updateHighlights();
+        this._recordingStart = Date.now();
+        this.layoutDoc._timeStampOnEnter = true;
     }
 
     public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
@@ -197,9 +204,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     dispatchTransaction = (tx: Transaction) => {
+        let timeStamp;
+        clearTimeout(timeStamp);
+        console.log("hi");
         if (this._editorView) {
+
             const metadata = tx.selection.$from.marks().find((m: Mark) => m.type === schema.marks.metadata);
             if (metadata) {
+
                 const range = tx.selection.$from.blockRange(tx.selection.$to);
                 let text = range ? tx.doc.textBetween(range.start, range.end) : "";
                 let textEndSelection = tx.selection.to;
@@ -221,6 +233,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     this.dataDoc[key] = value;
                 }
             }
+
             const state = this._editorView.state.apply(tx);
             this._editorView.updateState(state);
             (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks);
@@ -234,19 +247,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             const json = JSON.stringify(state.toJSON());
             let unchanged = true;
             const effectiveAcl = GetEffectiveAcl(this.dataDoc);
+
+
             if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) {
                 if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) {
                     this._applyingChange = true;
                     (curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())));
                     if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
                         if (json.replace(/"selection":.*/, "") !== curLayout?.Data.replace(/"selection":.*/, "")) {
+                            console.log("type");
+                            if (!this._pause && !this.layoutDoc._timeStampOnEnter) {
+                                console.log("started");
+                                timeStamp = setTimeout(() => this.pause(), 10 * 1000);
+                            }
+
+                            if (this._pause) {
+                                this._pause = false;
+                                this.insertTime();
+                            }
                             !curText && tx.storedMarks?.map(m => m.type.name === "pFontSize" && (Doc.UserDoc().fontSize = this.layoutDoc._fontSize = m.attrs.fontSize));
                             !curText && tx.storedMarks?.map(m => m.type.name === "pFontFamily" && (Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily));
                             this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText);
                             this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
                             ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: curText });
                             unchanged = false;
+
                         }
+
                     } else { // if we've deleted all the text in a note driven by a template, then restore the template data
                         this.dataDoc[this.props.fieldKey] = undefined;
                         this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((curProto || curTemp).Data)));
@@ -260,6 +287,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     }
                 }
             } else {
+
                 const json = JSON.parse(Cast(this.dataDoc[this.fieldKey], RichTextField)?.Data!);
                 json.selection = state.toJSON().selection;
                 this._editorView.updateState(EditorState.fromJSON(this.config, json));
@@ -267,6 +295,66 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         }
     }
 
+    pause = () => this._pause = true;
+
+    formatTime = (time: number) => {
+        const hours = Math.floor(time / 60 / 60);
+        const minutes = Math.floor(time / 60) - (hours * 60);
+        const seconds = time % 60;
+
+        return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
+    }
+
+    insertTime = () => {
+        let linkTime;
+        if (this._first) {
+            this._first = false;
+            DocListCast(this.dataDoc.links).map((l, i) => {
+                let la1 = l.anchor1 as Doc;
+                let la2 = l.anchor2 as Doc;
+                this._linkTime = NumCast(l.anchor2_timecode);
+                if (Doc.AreProtosEqual(la2, this.dataDoc)) {
+                    la1 = l.anchor2 as Doc;
+                    la2 = l.anchor1 as Doc;
+                    this._linkTime = NumCast(l.anchor1_timecode);
+                }
+
+            })
+
+
+
+        }
+        this._currentTime = Date.now();
+        let time;
+        console.log(this._linkTime);
+        this._linkTime ? time = this.formatTime(Math.round(this._linkTime + this._currentTime / 1000 - this._recordingStart / 1000)) : time = null;
+
+        if (this._editorView) {
+            const state = this._editorView.state;
+            const now = Date.now();
+            let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
+            if (!this._break && state.selection.to !== state.selection.from) {
+                for (let i = state.selection.from; i <= state.selection.to; i++) {
+                    const pos = state.doc.resolve(i);
+                    const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark);
+                    if (um) {
+                        mark = um;
+                        break;
+                    }
+                }
+            }
+            if (time) {
+                let value = "";
+                this._break = false;
+                value = this.layoutDoc._timeStampOnEnter ? "[" + time + "] " : "\n" + "[" + time + "] ";
+                console.log(value);
+                const from = state.selection.from;
+                const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
+                this._editorView.dispatch(this._editorView.state.tr.insertText(value));
+            }
+        }
+    }
+
     updateTitle = () => {
         if ((this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing
             StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.rootDoc.customTitle) {
@@ -501,6 +589,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         uicontrols.push({ description: `${this.layoutDoc._showSidebar ? "Hide" : "Show"} Sidebar`, event: () => this.layoutDoc._showSidebar = !this.layoutDoc._showSidebar, icon: "expand-arrows-alt" });
         uicontrols.push({ description: `${this.layoutDoc._showAudio ? "Hide" : "Show"} Dictation Icon`, event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" });
         uicontrols.push({ description: "Show Highlights...", noexpand: true, subitems: highlighting, icon: "hand-point-right" });
+        uicontrols.push({ description: `Create TimeStamp When ${this.layoutDoc._timeStampOnEnter ? "Pause" : "Enter"}`, event: () => this.layoutDoc._timeStampOnEnter = !this.layoutDoc._timeStampOnEnter, icon: "expand-arrows-alt" });
         !Doc.UserDoc().noviceMode && uicontrols.push({
             description: "Broadcast Message", event: () => DocServer.GetRefField("rtfProto").then(proto =>
                 proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.rootDoc[this.fieldKey], RichTextField)?.Text)), icon: "expand-arrows-alt"
@@ -594,6 +683,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime();
             this._break = false;
             value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value;
+            console.log(value);
             const from = state.selection.from;
             const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
             this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1)));
@@ -1295,30 +1385,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         }
         e.stopPropagation();
         if (e.key === "Tab" || e.key === "Enter") {
-            // console.log(this._recording);
-            // if (this._editorView) {
-            //     const state = this._editorView.state;
-            //     const now = Date.now();
-            //     let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) });
-            //     if (!this._break && state.selection.to !== state.selection.from) {
-            //         for (let i = state.selection.from; i <= state.selection.to; i++) {
-            //             const pos = state.doc.resolve(i);
-            //             const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark);
-            //             if (um) {
-            //                 mark = um;
-            //                 break;
-            //             }
-            //         }
-            //     }
-            //     const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime();
-            //     this._break = false;
-            //     let value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000;
-            //     //let value = "[0:02]";
-            //     const from = state.selection.from;
-            //     const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
-
-            //     this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1)));
-            // }
+            if (e.key === "Enter" && this.layoutDoc._timeStampOnEnter) {
+                this.insertTime();
+            }
             e.preventDefault();
         }
         if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) {
@@ -1371,6 +1440,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
         TraceMobx();
+        trace();
+        // if (this.props.Document.recordingStart) {
+        //     console.log(DateCast(this.props.Document.recordingStart).date.getTime());
+        // }
+
         const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
         const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
-- 
cgit v1.2.3-70-g09d2


From b827bdfecc5646b479c7e5654ed98243de91cf9a Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 6 Aug 2020 17:24:56 -0700
Subject: cleaned up code and fixed bugs

---
 src/client/views/nodes/AudioBox.tsx                | 415 ++++++---------------
 src/client/views/nodes/AudioResizer.scss           |  11 -
 src/client/views/nodes/AudioResizer.tsx            |  48 ---
 .../views/nodes/formattedText/FormattedTextBox.tsx |  18 +-
 4 files changed, 114 insertions(+), 378 deletions(-)
 delete mode 100644 src/client/views/nodes/AudioResizer.scss
 delete mode 100644 src/client/views/nodes/AudioResizer.tsx

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 1d060120e..11dfe5fe6 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -60,7 +60,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _start: number = 0;
     _hold: boolean = false;
     _left: boolean = false;
-    _amount: number = 1;
     _markers: Array<any> = [];
     _first: boolean = false;
     _dragging = false;
@@ -77,7 +76,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @observable private _height: number = NumCast(this.layoutDoc.height);
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
-    @observable private _repeat: boolean = false;
     @computed get audioState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.audioState as (undefined | "recording" | "paused" | "playing"); }
     set audioState(value) { this.dataDoc.audioState = value; }
     public static SetScrubTime = (timeInMillisFrom1970: number) => { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); };
@@ -126,36 +124,38 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 const sel = selected.length ? selected[0].props.Document : undefined;
                 let link;
                 if (sel) {
-                    // for determining if the link is created after recording (since it will use linkTIme rather than creation date)
-                    DocListCast(sel.links).map((l, i) => {
+                    // for determining if the link is created after recording (since it will use linkTime rather than creation date)
+                    DocListCast(this.dataDoc.links).map((l, i) => {
                         let la1 = l.anchor1 as Doc;
                         let la2 = l.anchor2 as Doc;
-                        let linkTime = NumCast(l.anchor2_timecode);
-                        let endTime;
-                        if (Doc.AreProtosEqual(la1, this.dataDoc)) {
-                            la1 = l.anchor2 as Doc;
-                            la2 = l.anchor1 as Doc;
-                            linkTime = NumCast(l.anchor1_timecode);
-                        }
-                        if (la2.audioStart) {
-                            linkTime = NumCast(la2.audioStart);
-                        }
+                        if (la1 === sel || la2 === sel) { // if the selected document is linked to this audio 
+                            let linkTime = NumCast(l.anchor2_timecode);
+                            let endTime;
+                            if (Doc.AreProtosEqual(la1, this.dataDoc)) {
+                                la1 = l.anchor2 as Doc;
+                                la2 = l.anchor1 as Doc;
+                                linkTime = NumCast(l.anchor1_timecode);
+                            }
+                            if (la2.audioStart) {
+                                linkTime = NumCast(la2.audioStart);
+                            }
 
-                        if (la1.audioStart) {
-                            linkTime = NumCast(la1.audioStart);
-                        }
+                            if (la1.audioStart) {
+                                linkTime = NumCast(la1.audioStart);
+                            }
 
-                        if (la1.audioEnd) {
-                            endTime = NumCast(la1.audioEnd);
-                        }
+                            if (la1.audioEnd) {
+                                endTime = NumCast(la1.audioEnd);
+                            }
 
-                        if (la2.audioEnd) {
-                            endTime = NumCast(la2.audioEnd);
-                        }
+                            if (la2.audioEnd) {
+                                endTime = NumCast(la2.audioEnd);
+                            }
 
-                        if (linkTime) {
-                            link = true;
-                            this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime);
+                            if (linkTime) {
+                                link = true;
+                                this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && (endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime));
+                            }
                         }
                     });
                 }
@@ -189,19 +189,19 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         }
     }
 
+    // pause play back
     pause = action(() => {
-        if (this._repeat) {
-            this.playFrom(0);
-        } else {
-            this._ele!.pause();
-            this.audioState = "paused";
-        }
+        console.log("pause");
+        this._ele!.pause();
+        this.audioState = "paused";
     });
 
+    // play audio for documents created during recording 
     playFromTime = (absoluteTime: number) => {
         this.recordingStart && this.playFrom((absoluteTime - this.recordingStart) / 1000);
     }
 
+    // play back the audio from time
     @action
     playFrom = (seekTimeInSeconds: number, endTime: number = this.dataDoc.duration) => {
         let play;
@@ -220,15 +220,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 this._ele.play();
                 runInAction(() => this.audioState = "playing");
                 if (endTime !== this.dataDoc.duration) {
-                    play = setTimeout(() => this.pause(), (this._duration) * 1000);
+                    play = setTimeout(() => this.pause(), (this._duration) * 1000); // use setTimeout to play a specific duration
                 }
-            } else { // this is getting called because time is greater than duration
+            } else {
                 this.pause();
             }
         }
     }
 
-
+    // update the recording time
     updateRecordTime = () => {
         if (this.audioState === "recording") {
             if (this._paused) {
@@ -241,6 +241,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         }
     }
 
+    // starts recording
     recordAudioAnnotation = async () => {
         this._stream = await navigator.mediaDevices.getUserMedia({ audio: true });
         this._recorder = new MediaRecorder(this._stream);
@@ -259,6 +260,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         setTimeout(() => this._recorder && this.stopRecording(), 60 * 60 * 1000); // stop after an hour
     }
 
+    // context menu
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
         funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when link is selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" });
@@ -268,6 +270,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
+    // stops the recording 
     stopRecording = action(() => {
         this._recorder.stop();
         this._recorder = undefined;
@@ -278,6 +281,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1));
     });
 
+    // button for starting and stopping the recording
     recordClick = (e: React.MouseEvent) => {
         if (e.button === 0 && !e.ctrlKey) {
             this._recorder ? this.stopRecording() : this.recordAudioAnnotation();
@@ -285,14 +289,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         }
     }
 
+    // for play button
     onPlay = (e: any) => {
         this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1);
         e.stopPropagation();
     }
-    onStop = (e: any) => {
-        this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect;
-        e.stopPropagation();
-    }
+
+    // creates a text document for dictation
     onFile = (e: any) => {
         const newDoc = Docs.Create.TextDocument("", {
             title: "", _chromeStatus: "disabled",
@@ -306,125 +309,21 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         e.stopPropagation();
     }
 
+    // ref for updating time
     setRef = (e: HTMLAudioElement | null) => {
         e?.addEventListener("timeupdate", this.timecodeChanged);
         e?.addEventListener("ended", this.pause);
         this._ele = e;
     }
 
+    // returns the path of the audio file
     @computed get path() {
         const field = Cast(this.props.Document[this.props.fieldKey], AudioField);
         const path = (field instanceof AudioField) ? field.url.href : "";
         return path === nullAudio ? "" : path;
     }
 
-    // @action
-    // buckets = () => {
-    //     let audioCtx = new (window.AudioContext)();
-    //     const buckets: number[] = [];
-
-    //     axios({ url: this.path, responseType: "arraybuffer" })
-    //         .then(response => runInAction(() => {
-    //             let audioData = response.data;
-
-    //             audioCtx.decodeAudioData(audioData, buffer => {
-    //                 let decodedAudioData = buffer.getChannelData(0);
-    //                 const NUMBER_OF_BUCKETS = 100;
-    //                 let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
-
-    //                 for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
-    //                     let startingPoint = i * bucketDataSize;
-    //                     let endingPoint = i * bucketDataSize + bucketDataSize;
-    //                     let max = 0;
-    //                     for (let j = startingPoint; j < endingPoint; j++) {
-    //                         if (decodedAudioData[j] > max) {
-    //                             max = decodedAudioData[j];
-    //                         }
-    //                     }
-    //                     let size = Math.abs(max);
-    //                     buckets.push(size / 2);
-    //                 }
-
-    //             });
-    //             return buckets
-    //         }));
-    // }
-
-    @action
-    buckets = async () => {
-        let audioCtx = new (window.AudioContext)();
-        const buckets: number[] = [];
-
-        axios({ url: this.path, responseType: "arraybuffer" })
-            .then(response => {
-                let audioData = response.data;
-
-                audioCtx.decodeAudioData(audioData, action(buffer => {
-                    let decodedAudioData = buffer.getChannelData(0);
-                    const NUMBER_OF_BUCKETS = 100;
-                    let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
-
-                    for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
-                        let startingPoint = i * bucketDataSize;
-                        let endingPoint = i * bucketDataSize + bucketDataSize;
-                        let max = 0;
-                        for (let j = startingPoint; j < endingPoint; j++) {
-                            if (decodedAudioData[j] > max) {
-                                max = decodedAudioData[j];
-                            }
-                        }
-                        let size = Math.abs(max);
-                        buckets.push(size / 2);
-                        this._buckets.push(size / 2);
-                    }
-
-                }));
-                return buckets;
-            });
-    }
-
-    @computed get peaks() {
-        // let audioCtx = new (window.AudioContext)();
-        // let buckets: number[] = [];
-
-        // return (async () => {
-        //     await axios({ url: this.path, responseType: "arraybuffer" })
-        //         .then(response => {
-        //             let audioData = response.data;
-
-        //             audioCtx.decodeAudioData(audioData, buffer => {
-        //                 let decodedAudioData = buffer.getChannelData(0);
-        //                 const NUMBER_OF_BUCKETS = 100;
-        //                 let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
-
-
-
-        //                 for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
-        //                     let startingPoint = i * bucketDataSize;
-        //                     let endingPoint = i * bucketDataSize + bucketDataSize;
-        //                     let max = 0;
-        //                     for (let j = startingPoint; j < endingPoint; j++) {
-        //                         if (decodedAudioData[j] > max) {
-        //                             max = decodedAudioData[j];
-        //                         }
-        //                     }
-        //                     let size = Math.abs(max);
-        //                     console.log(size);
-        //                     buckets.push(size / 2);
-        //                     console.log(buckets);
-        //                 }
-        //             });
-        //             console.log(buckets);
-        //             return buckets;
-        //         });
-        //     console.log(buckets.length);
-        //     return buckets;
-        // })();
-
-
-        return this.buckets();
-    }
-
+    // returns the html audio element
     @computed get audio() {
         const interactive = this.active() ? "-interactive" : "";
         return <audio ref={this.setRef} className={`audiobox-control${interactive}`}>
@@ -433,12 +332,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         </audio>;
     }
 
-    @action
-    onRepeat = (e: React.MouseEvent) => {
-        this._repeat = !this._repeat;
-        e.stopPropagation();
-    }
-
+    // pause the time during recording phase
     @action
     recordPause = (e: React.MouseEvent) => {
         this._pauseStart = new Date().getTime();
@@ -448,6 +342,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     }
 
+    // continue the recording
     @action
     recordPlay = (e: React.MouseEvent) => {
         this._pauseEnd = new Date().getTime();
@@ -457,12 +352,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     }
 
+    // return the total time paused to update the correct time
     @computed get pauseTime() {
         return (this._pauseEnd - this._pauseStart);
     }
 
+    // creates a new label 
     @action
     newMarker(marker: Doc) {
+        marker.data = "";
         if (this.dataDoc[this.annotationKey]) {
             this.dataDoc[this.annotationKey].push(marker);
         } else {
@@ -470,46 +368,43 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         }
     }
 
-    start(marker: number) {
-        console.log("start!");
+    // the starting time of the marker
+    start(startingPoint: number) {
         this._hold = true;
-        this._start = marker;
+        this._start = startingPoint;
     }
 
+    // creates a new marker
     @action
     end(marker: number) {
-        console.log("end!");
         this._hold = false;
-        //this._markers.push(Docs.Create.LabelDocument({ isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }))
         let newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
         newMarker.data = "";
         if (this.dataDoc[this.annotationKey]) {
-            this.dataDoc[this.annotationKey].push(newMarker); // onClick: ScriptField.MakeScript(`playFrom(${NumCast(this._start)}, ${NumCast(marker)})`)
+            this.dataDoc[this.annotationKey].push(newMarker);
         } else {
             this.dataDoc[this.annotationKey] = new List<Doc>([newMarker]);
         }
 
-
         this._start = 0;
-        this._amount++;
     }
 
+    // starting the drag event for marker resizing
     onPointerDown = (e: React.PointerEvent, m: any, left: boolean): void => {
         e.stopPropagation();
         e.preventDefault();
         this._isPointerDown = true;
-        console.log("click");
         this._currMarker = m;
         this._timeline?.setPointerCapture(e.pointerId);
         this._left = left;
 
-
         document.removeEventListener("pointermove", this.onPointerMove);
         document.addEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
         document.addEventListener("pointerup", this.onPointerUp);
     }
 
+    // ending the drag event for marker resizing
     @action
     onPointerUp = (e: PointerEvent): void => {
         e.stopPropagation();
@@ -526,6 +421,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         document.removeEventListener("pointerup", this.onPointerUp);
     }
 
+    // resizes the marker while dragging
     onPointerMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
@@ -537,24 +433,22 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
         const rect = await (e.target as any).getBoundingClientRect();
 
-        // if (e.target as HTMLElement === document.getElementById("timeline")) {
-
         let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
         this.changeMarker(this._currMarker, newTime);
-        // }
     }
 
+    // updates the marker with the new time
     @action
     changeMarker = (m: any, time: any) => {
         for (let i = 0; i < this.dataDoc[this.annotationKey].length; i++) {
             if (this.isSame(this.dataDoc[this.annotationKey][i], m)) {
-                // this._left ? this._markers[i][0] = time : this._markers[i][1] = time;
                 this._left ? this.dataDoc[this.annotationKey][i].audioStart = time : this.dataDoc[this.annotationKey][i].audioEnd = time;
             }
         }
     }
 
+    // checks if the two markers are the same with start and end time
     isSame = (m1: any, m2: any) => {
         if (m1.audioStart === m2.audioStart && m1.audioEnd === m2.audioEnd) {
             return true;
@@ -562,6 +456,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return false;
     }
 
+    // instantiates a new array of size 500 for marker layout
     markers = () => {
         const increment = NumCast(this.layoutDoc.duration) / 500;
         this._count = [];
@@ -571,38 +466,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     }
 
-    // Probably need a better way to format
-    // isOverlap = (m: any, i: number) => {
-    //     console.log("called");
-    //     let counter = 0;
-
-    //     if (this._first) {
-    //         this._markers = [];
-    //         this._first = false;
-    //     }
-    //     for (let i = 0; i < this._markers.length; i++) {
-    //         if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) {
-    //             counter++;
-    //             console.log(counter);
-    //         }
-    //     }
-
-    //     if (this.dataDoc.markerAmount < counter) {
-    //         this.dataDoc.markerAmount = counter;
-    //     }
-
-    //     this._markers.push(m);
-
-    //     return counter;
-    // }
-
+    // makes sure no markers overlaps each other by setting the correct position and width
     isOverlap = (m: any) => {
         if (this._first) {
             this._first = false;
             this.markers();
         }
-
-
         let max = 0
 
         for (let i = 0; i < 500; i++) {
@@ -613,8 +482,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                     max = this._count[i][1];
                 }
             }
-
-
         }
 
         for (let i = 0; i < 500; i++) {
@@ -630,76 +497,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return max - 1
     }
 
-
-    @action
-    onHover = () => {
-        this._dragging = true;
-    }
-
-    @action
-    onLeave = () => {
-        this._dragging = false;
-    }
-    // onMouseOver={this.onHover} onMouseLeave={this.onLeave}
-
-    change = (e: React.PointerEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-        const rect = (e.target as any).getBoundingClientRect();
-
-        const wasPaused = this.audioState === "paused";
-        this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
-        wasPaused && this.pause();
-        console.log("double!");
-    }
-
-    rangeScript = () => AudioBox.RangeScript;
-
-    labelScript = () => AudioBox.LabelScript;
-
-    // see if time is encapsulated by comparing time on both sides (for moving onto a new row in the timeline for the markers)
-    check = (e: React.PointerEvent) => {
-        if (e.target as HTMLElement === document.getElementById("timeline")) {
-            return true;
-        }
-    }
-
-    reset = () => {
-        this._first = true;
-    }
-
-    @computed get height() {
-        console.log(this.layoutDoc._height);
-        if (this.layoutDoc._height) {
-            return 0.8 * NumCast(this.layoutDoc._height)
-        }
-    }
-
-    // waveform() {
-    //     let wavesurfer: any;
-    //     if (WaveSurfer) {
-    //         this.path ?
-    //             wavesurfer = WaveSurfer.create({
-    //                 container: 'waveform',
-    //                 waveColor: "grey",
-    //                 progressColor: "blue"
-    //             })
-    //             :
-    //             wavesurfer = (null);
-    //     } else {
-    //         console.log("hi");
-    //     }
-
-    //     if (wavesurfer) {
-    //         wavesurfer.on('ready', function () {
-    //             wavesurfer.play();
-    //         });
-
-    //         wavesurfer.load(this.path);
-    //         console.log("hi");
-    //     }
-    // }
-
+    // returns the audio waveform
     @computed get waveform() {
         return <Waveform
             color={"darkblue"}
@@ -712,6 +510,43 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
             progressColor={"blue"} />;
     }
 
+    // decodes the audio file into peaks for generating the waveform
+    @action
+    buckets = async () => {
+        let audioCtx = new (window.AudioContext)();
+
+        axios({ url: this.path, responseType: "arraybuffer" })
+            .then(response => {
+                let audioData = response.data;
+
+                audioCtx.decodeAudioData(audioData, action(buffer => {
+                    let decodedAudioData = buffer.getChannelData(0);
+                    const NUMBER_OF_BUCKETS = 100;
+                    let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
+
+                    for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
+                        let startingPoint = i * bucketDataSize;
+                        let endingPoint = i * bucketDataSize + bucketDataSize;
+                        let max = 0;
+                        for (let j = startingPoint; j < endingPoint; j++) {
+                            if (decodedAudioData[j] > max) {
+                                max = decodedAudioData[j];
+                            }
+                        }
+                        let size = Math.abs(max);
+                        this._buckets.push(size / 2);
+                    }
+
+                }));
+            });
+    }
+
+    // Returns the peaks of the audio waveform
+    @computed get peaks() {
+        return this.buckets();
+    }
+
+    // for updating the width and height of the waveform with timeline ref
     timelineRef = (timeline: HTMLDivElement) => {
         const observer = new _global.ResizeObserver(action((entries: any) => {
             for (const entry of entries) {
@@ -724,6 +559,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._timeline = timeline;
     }
 
+    // update the width and height of the audio waveform
     @action
     update = (width: number, height: number) => {
         if (height) {
@@ -741,8 +577,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (context) {
                     context.scale(ratio1, ratio2)
                 }
-
-
             }
 
             let canvas1 = document.getElementsByTagName("canvas")[1];
@@ -758,36 +592,28 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (context) {
                     context.scale(ratio1, ratio2)
                 }
-
-                // let parent = canvas1.parentElement;
-                // if (parent) {
-                //     parent.style.width = `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration) * width}`;
-                //     parent.style.height = `${this._height}`;
-                // }
             }
         }
     }
 
+    rangeScript = () => AudioBox.RangeScript;
+
+    labelScript = () => AudioBox.LabelScript;
+
+    // for indicating the first marker that is rendered
+    reset = () => this._first = true;
 
     render() {
         trace();
         const interactive = this.active() ? "-interactive" : "";
         this.reset();
-        // this.waveform();
-        this.path && this._buckets.length !== 100 ? this.buckets() : null;
+        this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
                 <div className="audiobox-buttons">
                     <div className="audiobox-dictation" onClick={this.onFile}>
                         <FontAwesomeIcon style={{ width: "30px", background: this.layoutDoc.playOnSelect ? "yellow" : "rgba(0,0,0,0)" }} icon="file-alt" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
                     </div>
-                    {/* <button className={`audiobox-record${interactive}`} style={{ backgroundColor: this.audioState === "recording" ? "lightgrey" : "black" }}>
-                        {this.audioState === "recording" ?
-                            <div className="recording" style={{}}>
-                                10:00
-                                    <FontAwesomeIcon style={{ width: "100%" }} icon={"stop-circle"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
-                                <FontAwesomeIcon style={{ width: "100%" }} icon={"pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /> </div> : "RECORD"}
-                    </button> */}
                     {this.audioState === "recording" ?
                         <div className="recording" onClick={e => e.stopPropagation()}>
                             <div className="buttons" onClick={this.recordClick}>
@@ -798,19 +624,16 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             </div>
                             <div className="time">{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}</div>
                         </div>
-
                         :
                         <button className={`audiobox-record${interactive}`} style={{ backgroundColor: "black" }}>
                             RECORD
                             </button>}
                 </div> :
-                <div className="audiobox-controls" > {/*onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}*/}
+                <div className="audiobox-controls" >
                     <div className="audiobox-dictation"></div>
                     <div className="audiobox-player" >
                         <div className="audiobox-playhead" title={this.audioState === "paused" ? "play" : "pause"} onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%", position: "absolute", left: "0px", top: "5px", borderWidth: "thin", borderColor: "white" }} icon={this.audioState === "paused" ? "play" : "pause"} size={"1x"} /></div>
-                        {/* <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%", background: this.layoutDoc.playOnSelect ? "darkgrey" : "" }} icon="hand-point-left" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
-                        <div className="audiobox-playhead" onClick={this.onRepeat}><FontAwesomeIcon style={{ width: "100%", background: this._repeat ? "darkgrey" : "" }} icon="redo-alt" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div> */}
-                        <div className="audiobox-timeline" ref={this.timelineRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change}
+                        <div className="audiobox-timeline" ref={this.timelineRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }}
                             onPointerDown={e => {
                                 e.stopPropagation();
                                 e.preventDefault();
@@ -834,21 +657,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 }
                             }}>
                             <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
-                                {/* {console.log(this.peaks)} */}
-                                {/* <Waveform
-                                    color={"#000000"}
-                                    height={this._height}
-                                    barWidth={0.1}
-                                    pos={this.layoutDoc.currentTimecode}
-                                    duration={this.dataDoc.duration}
-                                    peaks={this._buckets.length === 100 ? this._buckets : undefined}
-
-                                    progressColor={"#0000ff"} /> */}
                                 {this.waveform}
-                                {/* {this.waveform} */}
                             </div>
                             {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
-                                // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
                                 (!m.isLabel) ?
                                     (this.layoutDoc.hideMarkers) ? (null) :
@@ -869,8 +680,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                                 ignoreAutoHeight={false}
                                                 bringToFront={emptyFunction}
                                                 scriptContext={this} />
-                                            {/* <LabelBox {... this.props} Document={m} /> */}
-                                            {/* <div className="click" onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}></div> */}
                                             <div className="resizer" onPointerDown={e => this.onPointerDown(e, m, false)}></div>
                                         </div>
                                     :
@@ -905,13 +714,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     linkTime = NumCast(l.anchor1_timecode);
                                 }
 
-                                if (la2.audioStart) {
+                                if (la2.audioStart && !la2.audioEnd) {
                                     linkTime = NumCast(la2.audioStart);
                                 }
 
                                 return !linkTime ? (null) :
                                     <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => e.stopPropagation()}>
-                                        {/* <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}> */}
                                         <DocumentView {...this.props}
                                             Document={l}
                                             NativeHeight={returnZero}
@@ -933,7 +741,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             })}
                             <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} />
                             {this.audio}
-
                         </div>
                         <div className="current-time">
                             {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
diff --git a/src/client/views/nodes/AudioResizer.scss b/src/client/views/nodes/AudioResizer.scss
deleted file mode 100644
index 892ad21e7..000000000
--- a/src/client/views/nodes/AudioResizer.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.resizer {
-    width: 0px;
-    height: 100%;
-    position: absolute;
-    right: 0px;
-    z-index: 999;
-    cursor: e-resize;
-    content: " ";
-    display: inline-block;
-    border-left: 20px solid transparent;
-}
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioResizer.tsx b/src/client/views/nodes/AudioResizer.tsx
deleted file mode 100644
index f9ab8353f..000000000
--- a/src/client/views/nodes/AudioResizer.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { observer } from "mobx-react"
-import React = require("react");
-import "./AudioResizer.scss";
-
-@observer
-export class AudioResizer extends React.Component {
-    private _isPointerDown = false;
-
-    onPointerDown = (e: React.PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        this._isPointerDown = true;
-        console.log("click");
-
-        document.removeEventListener("pointermove", this.onPointerMove);
-        document.addEventListener("pointermove", this.onPointerMove);
-        document.removeEventListener("pointerup", this.onPointerUp);
-        document.addEventListener("pointerup", this.onPointerUp);
-    }
-
-    onPointerUp = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        this._isPointerDown = false;
-
-        document.removeEventListener("pointermove", this.onPointerMove);
-        document.removeEventListener("pointerup", this.onPointerUp);
-    }
-
-    onPointerMove = (e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
-        console.log("drag");
-
-        if (!this._isPointerDown) {
-            return;
-        }
-
-        let resize = document.getElementById("resizer");
-        if (resize) {
-            resize.style.right += e.movementX;
-        }
-    }
-
-    render() {
-        return <div className="resizer" onPointerDown={this.onPointerDown}></div>
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 91940466f..fabda4d20 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -206,7 +206,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     dispatchTransaction = (tx: Transaction) => {
         let timeStamp;
         clearTimeout(timeStamp);
-        console.log("hi");
         if (this._editorView) {
 
             const metadata = tx.selection.$from.marks().find((m: Mark) => m.type === schema.marks.metadata);
@@ -255,12 +254,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     (curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())));
                     if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended)
                         if (json.replace(/"selection":.*/, "") !== curLayout?.Data.replace(/"selection":.*/, "")) {
-                            console.log("type");
                             if (!this._pause && !this.layoutDoc._timeStampOnEnter) {
-                                console.log("started");
-                                timeStamp = setTimeout(() => this.pause(), 10 * 1000);
+                                timeStamp = setTimeout(() => this.pause(), 10 * 1000); // 10 seconds delay for time stamp
                             }
 
+                            // if 10 seconds have passed, insert time stamp the next time you type
                             if (this._pause) {
                                 this._pause = false;
                                 this.insertTime();
@@ -305,6 +303,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
     }
 
+    // for inserting timestamps 
     insertTime = () => {
         let linkTime;
         if (this._first) {
@@ -320,13 +319,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 }
 
             })
-
-
-
         }
         this._currentTime = Date.now();
         let time;
-        console.log(this._linkTime);
         this._linkTime ? time = this.formatTime(Math.round(this._linkTime + this._currentTime / 1000 - this._recordingStart / 1000)) : time = null;
 
         if (this._editorView) {
@@ -347,7 +342,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 let value = "";
                 this._break = false;
                 value = this.layoutDoc._timeStampOnEnter ? "[" + time + "] " : "\n" + "[" + time + "] ";
-                console.log(value);
                 const from = state.selection.from;
                 const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
                 this._editorView.dispatch(this._editorView.state.tr.insertText(value));
@@ -683,7 +677,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime();
             this._break = false;
             value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value;
-            console.log(value);
             const from = state.selection.from;
             const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark);
             this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1)));
@@ -1440,11 +1433,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
         TraceMobx();
-        trace();
-        // if (this.props.Document.recordingStart) {
-        //     console.log(DateCast(this.props.Document.recordingStart).date.getTime());
-        // }
-
         const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
         const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
-- 
cgit v1.2.3-70-g09d2


From 301b10ba693dc76ebcd42d3fa4020410f2092bee Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 6 Aug 2020 23:13:50 -0400
Subject: fixed lint warnings

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 48 +++++++-------
 src/client/views/nodes/AudioBox.tsx                | 75 ++++++++++++----------
 src/client/views/nodes/PresBox.tsx                 |  4 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 4 files changed, 67 insertions(+), 63 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5b1f3c01c..ef4b7b9d2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1504,32 +1504,30 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
 
     @computed get presPaths() {
         const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
-        if (PresBox.Instance) return (
-            <>
-                {!this.props.presPaths ? (null) : <><div>{PresBox.Instance.order}</div>
-                    <svg className={presPaths}>
-                        <defs>
-                            <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
-                                <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
-                            </marker>
-                            <marker id="square" markerWidth="3" markerHeight="3" overflow="visible"
-                                refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
-                                <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#69a6db" />
-                            </marker>
-                            <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
-                                orient="auto" overflow="visible">
-                                <rect x="1" y="1" width="5" height="5" fill="#69a6db" />
-                            </marker>
-
-                            <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="7"
-                                orient="auto" overflow="visible">
-                                <path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
-                            </marker>
-                        </defs>;
+        return !(PresBox.Instance) ? (null) : (<>
+            {!this.props.presPaths ? (null) : <><div>{PresBox.Instance.order}</div>
+                <svg className={presPaths}>
+                    <defs>
+                        <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                            <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
+                        </marker>
+                        <marker id="square" markerWidth="3" markerHeight="3" overflow="visible"
+                            refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                            <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#69a6db" />
+                        </marker>
+                        <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
+                            orient="auto" overflow="visible">
+                            <rect x="1" y="1" width="5" height="5" fill="#69a6db" />
+                        </marker>
+
+                        <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="7"
+                            orient="auto" overflow="visible">
+                            <path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
+                        </marker>
+                    </defs>;
                     {PresBox.Instance.paths}
-                    </svg></>}
-            </>
-        );
+                </svg></>}
+        </>);
     }
 
     render() {
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 11fecc0c2..eba1046b2 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -23,8 +23,8 @@ import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 import { List } from "../../../fields/List";
 import { Scripting } from "../../util/Scripting";
-import Waveform from "react-audio-waveform"
-import axios from "axios"
+import Waveform from "react-audio-waveform";
+import axios from "axios";
 const _global = (window /* browser */ || global /* node */) as any;
 
 declare class MediaRecorder {
@@ -375,7 +375,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @action
     end(marker: number) {
         this._hold = false;
-        let newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
+        const newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
         newMarker.data = "";
         if (this.dataDoc[this.annotationKey]) {
             this.dataDoc[this.annotationKey].push(newMarker);
@@ -429,7 +429,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
         const rect = await (e.target as any).getBoundingClientRect();
 
-        let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+        const newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
         this.changeMarker(this._currMarker, newTime);
     }
@@ -437,11 +437,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     // updates the marker with the new time
     @action
     changeMarker = (m: any, time: any) => {
-        for (let i = 0; i < this.dataDoc[this.annotationKey].length; i++) {
-            if (this.isSame(this.dataDoc[this.annotationKey][i], m)) {
-                this._left ? this.dataDoc[this.annotationKey][i].audioStart = time : this.dataDoc[this.annotationKey][i].audioEnd = time;
+        DocListCast(this.dataDoc[this.annotationKey]).forEach((marker: Doc) => {
+            if (this.isSame(marker, m)) {
+                this._left ? marker.audioStart = time : marker.audioEnd = time;
             }
-        }
+        });
     }
 
     // checks if the two markers are the same with start and end time
@@ -457,7 +457,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         const increment = NumCast(this.layoutDoc.duration) / 500;
         this._count = [];
         for (let i = 0; i < 500; i++) {
-            this._count.push([increment * i, 0])
+            this._count.push([increment * i, 0]);
         }
 
     }
@@ -468,7 +468,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
             this._first = false;
             this.markers();
         }
-        let max = 0
+        let max = 0;
 
         for (let i = 0; i < 500; i++) {
             if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) {
@@ -490,7 +490,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         if (this.dataDoc.markerAmount < max) {
             this.dataDoc.markerAmount = max;
         }
-        return max - 1
+        return max - 1;
     }
 
     // returns the audio waveform
@@ -509,27 +509,27 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     // decodes the audio file into peaks for generating the waveform
     @action
     buckets = async () => {
-        let audioCtx = new (window.AudioContext)();
+        const audioCtx = new (window.AudioContext)();
 
         axios({ url: this.path, responseType: "arraybuffer" })
             .then(response => {
-                let audioData = response.data;
+                const audioData = response.data;
 
                 audioCtx.decodeAudioData(audioData, action(buffer => {
-                    let decodedAudioData = buffer.getChannelData(0);
+                    const decodedAudioData = buffer.getChannelData(0);
                     const NUMBER_OF_BUCKETS = 100;
-                    let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
+                    const bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
 
                     for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
-                        let startingPoint = i * bucketDataSize;
-                        let endingPoint = i * bucketDataSize + bucketDataSize;
+                        const startingPoint = i * bucketDataSize;
+                        const endingPoint = i * bucketDataSize + bucketDataSize;
                         let max = 0;
                         for (let j = startingPoint; j < endingPoint; j++) {
                             if (decodedAudioData[j] > max) {
                                 max = decodedAudioData[j];
                             }
                         }
-                        let size = Math.abs(max);
+                        const size = Math.abs(max);
                         this._buckets.push(size / 2);
                     }
 
@@ -560,36 +560,36 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     update = (width: number, height: number) => {
         if (height) {
             this._height = 0.8 * NumCast(this.layoutDoc._height);
-            let canvas2 = document.getElementsByTagName("canvas")[0];
+            const canvas2 = document.getElementsByTagName("canvas")[0];
             if (canvas2) {
-                let oldWidth = canvas2.width;
-                let oldHeight = canvas2.height;
+                const oldWidth = canvas2.width;
+                const oldHeight = canvas2.height;
                 canvas2.style.height = `${this._height}`;
                 canvas2.style.width = `${width}`;
 
-                let ratio1 = oldWidth / window.innerWidth;
-                let ratio2 = oldHeight / window.innerHeight;
-                let context = canvas2.getContext('2d');
+                const ratio1 = oldWidth / window.innerWidth;
+                const ratio2 = oldHeight / window.innerHeight;
+                const context = canvas2.getContext('2d');
                 if (context) {
-                    context.scale(ratio1, ratio2)
+                    context.scale(ratio1, ratio2);
                 }
             }
 
-            let canvas1 = document.getElementsByTagName("canvas")[1];
+            const canvas1 = document.getElementsByTagName("canvas")[1];
             if (canvas1) {
-                let oldWidth = canvas1.width;
-                let oldHeight = canvas1.height;
+                const oldWidth = canvas1.width;
+                const oldHeight = canvas1.height;
                 canvas1.style.height = `${this._height}`;
                 canvas1.style.width = `${width}`;
 
-                let ratio1 = oldWidth / window.innerWidth;
-                let ratio2 = oldHeight / window.innerHeight;
-                let context = canvas1.getContext('2d');
+                const ratio1 = oldWidth / window.innerWidth;
+                const ratio2 = oldHeight / window.innerHeight;
+                const context = canvas1.getContext('2d');
                 if (context) {
-                    context.scale(ratio1, ratio2)
+                    context.scale(ratio1, ratio2);
                 }
 
-                let parent = canvas1.parentElement;
+                const parent = canvas1.parentElement;
                 if (parent) {
                     parent.style.width = `${width}`;
                     parent.style.height = `${this._height}`;
@@ -665,7 +665,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 (!m.isLabel) ?
                                     (this.layoutDoc.hideMarkers) ? (null) :
                                         rect =
-                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${formatTime(Math.round(NumCast(m.audioEnd)))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`, top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%` }} onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} >
+                                        <div key={i} id={"audiobox-marker-container1"} className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"}
+                                            title={`${formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${formatTime(Math.round(NumCast(m.audioEnd)))}`}
+                                            style={{
+                                                left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`,
+                                                width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`,
+                                                top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%`
+                                            }}
+                                            onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} >
                                             <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
                                             <DocumentView {...this.props}
                                                 Document={m}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 230137584..502fd51f3 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -137,7 +137,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             this.gotoDocument(nextSelected, this.itemIndex);
             const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
             if (activeNext && targetNext.type === DocumentType.AUDIO && activeNext.playAuto) {
-            } else { this._moveOnFromAudio = false };
+            } else this._moveOnFromAudio = false;
         }
     }
 
@@ -1646,7 +1646,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 </select>
                 <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length > 0 ? 1 : 0.3 }}>
                     <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left" onClick={() => { if (this.childDocs.length > 0) this.layoutDoc.presStatus = "manual" }}>
+                        <div className="presBox-button-left" onClick={() => (this.childDocs.length > 0) && (this.layoutDoc.presStatus = "manual")}>
                             <FontAwesomeIcon icon={"play-circle"} />
                             <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
                         </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 4b06f2800..b0bf54be6 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -305,7 +305,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     // for inserting timestamps 
     insertTime = () => {
-        let linkTime;
         if (this._first) {
             this._first = false;
             DocListCast(this.dataDoc.links).map((l, i) => {
@@ -318,7 +317,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     this._linkTime = NumCast(l.anchor1_timecode);
                 }
 
-            })
+            });
         }
         this._currentTime = Date.now();
         let time;
-- 
cgit v1.2.3-70-g09d2

