From 58ee7315c4ce7068456dffcdfc02bd57b4c7a37f Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sat, 4 Jul 2020 21:31:16 -0700
Subject: modified playOnSelect and created repeat button

---
 src/client/views/nodes/AudioBox.tsx | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index d5288fff6..78d714ca9 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -53,6 +53,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _stream: MediaStream | undefined;
 
     @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); };
@@ -106,8 +107,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     pause = action(() => {
-        this._ele!.pause();
-        this.audioState = "paused";
+        if (this._repeat) {
+            this.playFrom(0);
+        } else {
+            this._ele!.pause();
+            this.audioState = "paused";
+        }
     });
 
     playFromTime = (absoluteTime: number) => {
@@ -222,6 +227,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         </audio>;
     }
 
+    @action
+    onRepeat = (e: React.MouseEvent) => {
+        this._repeat = !this._repeat;
+        e.stopPropagation();
+    }
+
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -231,13 +242,19 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                         <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" ? "red" : "black" }}>
-                        {this.audioState === "recording" ? "STOP" : "RECORD"}
+                        {this.audioState === "recording" ?
+                            <div className="recording" >
+                                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>
                 </div> :
-                <div className="audiobox-controls">
-                    <div className="audiobox-player" onClick={this.onPlay}>
-                        <div className="audiobox-playhead"> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
-                        <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%", background: this.layoutDoc.playOnSelect ? "yellow" : "dimGray" }} icon="hand-point-left" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
+                <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
+                    <div className="audiobox-player" >
+                        <div className="audiobox-playhead" onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></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" onClick={e => e.stopPropagation()}
                             onPointerDown={e => {
                                 if (e.button === 0 && !e.ctrlKey) {
-- 
cgit v1.2.3-70-g09d2


From 52a4bf82c7207d27a267f9fded63d2d212007fbe Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 5 Jul 2020 15:53:16 -0700
Subject: added things

---
 src/client/views/nodes/AudioBox.tsx | 37 +++++++++++--------------------------
 1 file changed, 11 insertions(+), 26 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 78d714ca9..2b24268fe 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -8,7 +8,7 @@ import { ViewBoxBaseComponent } from "../DocComponent";
 import { makeInterface, createSchema } from "../../../fields/Schema";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
-import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx";
+import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace } from "mobx";
 import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Doc, DocListCast } from "../../../fields/Doc";
@@ -53,7 +53,6 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _stream: MediaStream | undefined;
 
     @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); };
@@ -81,7 +80,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
                 const sel = selected.length ? selected[0].props.Document : undefined;
-                this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
+                //this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
                 this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
             });
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime));
@@ -107,12 +106,8 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     pause = action(() => {
-        if (this._repeat) {
-            this.playFrom(0);
-        } else {
-            this._ele!.pause();
-            this.audioState = "paused";
-        }
+        this._ele!.pause();
+        this.audioState = "paused";
     });
 
     playFromTime = (absoluteTime: number) => {
@@ -125,6 +120,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                     setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000);
                 } else {
                     this.pause();
+                    console.log("wtf");
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
                 this._ele.currentTime = seekTimeInSeconds;
@@ -187,6 +183,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     onPlay = (e: any) => {
+        console.log("click");
         this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1);
         e.stopPropagation();
     }
@@ -227,12 +224,6 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         </audio>;
     }
 
-    @action
-    onRepeat = (e: React.MouseEvent) => {
-        this._repeat = !this._repeat;
-        e.stopPropagation();
-    }
-
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -242,19 +233,13 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                         <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" ? "red" : "black" }}>
-                        {this.audioState === "recording" ?
-                            <div className="recording" >
-                                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"}
+                        {this.audioState === "recording" ? "STOP" : "RECORD"}
                     </button>
                 </div> :
-                <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
-                    <div className="audiobox-player" >
-                        <div className="audiobox-playhead" onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></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-controls">
+                    <div className="audiobox-player" onClick={this.onPlay}>
+                        <div className="audiobox-playhead"> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
+                        <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%", background: this.layoutDoc.playOnSelect ? "yellow" : "dimGray" }} icon="hand-point-left" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
                         <div className="audiobox-timeline" onClick={e => e.stopPropagation()}
                             onPointerDown={e => {
                                 if (e.button === 0 && !e.ctrlKey) {
-- 
cgit v1.2.3-70-g09d2


From a79e9053bb167ea10561619d31b65a582b457d92 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 5 Jul 2020 19:44:55 -0700
Subject: Revert "added things"

This reverts commit 52a4bf82c7207d27a267f9fded63d2d212007fbe.
---
 src/client/views/nodes/AudioBox.tsx | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 2b24268fe..78d714ca9 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -8,7 +8,7 @@ import { ViewBoxBaseComponent } from "../DocComponent";
 import { makeInterface, createSchema } from "../../../fields/Schema";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
-import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace } from "mobx";
+import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx";
 import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Doc, DocListCast } from "../../../fields/Doc";
@@ -53,6 +53,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _stream: MediaStream | undefined;
 
     @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); };
@@ -80,7 +81,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
                 const sel = selected.length ? selected[0].props.Document : undefined;
-                //this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
+                this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
                 this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
             });
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime));
@@ -106,8 +107,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     pause = action(() => {
-        this._ele!.pause();
-        this.audioState = "paused";
+        if (this._repeat) {
+            this.playFrom(0);
+        } else {
+            this._ele!.pause();
+            this.audioState = "paused";
+        }
     });
 
     playFromTime = (absoluteTime: number) => {
@@ -120,7 +125,6 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                     setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000);
                 } else {
                     this.pause();
-                    console.log("wtf");
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
                 this._ele.currentTime = seekTimeInSeconds;
@@ -183,7 +187,6 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     onPlay = (e: any) => {
-        console.log("click");
         this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1);
         e.stopPropagation();
     }
@@ -224,6 +227,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         </audio>;
     }
 
+    @action
+    onRepeat = (e: React.MouseEvent) => {
+        this._repeat = !this._repeat;
+        e.stopPropagation();
+    }
+
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -233,13 +242,19 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                         <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" ? "red" : "black" }}>
-                        {this.audioState === "recording" ? "STOP" : "RECORD"}
+                        {this.audioState === "recording" ?
+                            <div className="recording" >
+                                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>
                 </div> :
-                <div className="audiobox-controls">
-                    <div className="audiobox-player" onClick={this.onPlay}>
-                        <div className="audiobox-playhead"> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
-                        <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%", background: this.layoutDoc.playOnSelect ? "yellow" : "dimGray" }} icon="hand-point-left" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
+                <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
+                    <div className="audiobox-player" >
+                        <div className="audiobox-playhead" onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></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" onClick={e => e.stopPropagation()}
                             onPointerDown={e => {
                                 if (e.button === 0 && !e.ctrlKey) {
-- 
cgit v1.2.3-70-g09d2


From 2961955e2e6ee993252435f0e1358b305c0817b3 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Tue, 7 Jul 2020 14:09:07 -0700
Subject: pause and time

---
 src/client/views/nodes/AudioBox.scss | 33 ++++++++++++++++---
 src/client/views/nodes/AudioBox.tsx  | 61 +++++++++++++++++++++++++++++++-----
 2 files changed, 81 insertions(+), 13 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 2655f2377..ad4b94b91 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -46,13 +46,36 @@
         height: 100%;
         position: relative;
 
-        .recording {
-            width: 100%;
+        
+    }
+
+    .recording {
+        margin-top: auto;
+        margin-bottom: auto;
+        width: 100%;
+        height: 80%;
+        position: relative;
+        padding-right: 5px;
+        display: flex;
+
+        .time {
+            position: relative;
             height: 100%;
+            width: 100%;
+            font-size: 20;
+            text-align: center;
+        }
+
+        .buttons {
             position: relative;
-            display: flex;
-            padding-left: 2px;
-            background: lightgrey;
+            margin-top: auto;
+            margin-bottom: auto;
+            width: 25px;
+            padding: 5px;
+        }
+
+        .buttons:hover {
+            background-color: darkgrey;
         }
     }
 
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 78d714ca9..ec8992249 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -50,8 +50,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _ele: HTMLAudioElement | null = null;
     _recorder: any;
     _recordStart = 0;
+    _pauseStart = 0;
+    _pauseEnd = 0;
+    _pausedTime = 0;
     _stream: MediaStream | undefined;
 
+    @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"); }
@@ -139,8 +143,13 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
 
     updateRecordTime = () => {
         if (this.audioState === "recording") {
-            setTimeout(this.updateRecordTime, 30);
-            this.layoutDoc.currentTimecode = (new Date().getTime() - this._recordStart) / 1000;
+            if (this._paused) {
+                setTimeout(this.updateRecordTime, 30);
+                this._pausedTime += (new Date().getTime() - this._recordStart) / 1000;
+            } else {
+                setTimeout(this.updateRecordTime, 30);
+                this.layoutDoc.currentTimecode = (new Date().getTime() - this._recordStart - this.pauseTime) / 1000;
+            }
         }
     }
 
@@ -172,7 +181,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     stopRecording = action(() => {
         this._recorder.stop();
         this._recorder = undefined;
-        this.dataDoc.duration = (new Date().getTime() - this._recordStart) / 1000;
+        this.dataDoc.duration = (new Date().getTime() - this._recordStart - this.pauseTime) / 1000;
         this.audioState = "paused";
         this._stream?.getAudioTracks()[0].stop();
         const ind = DocUtils.ActiveRecordings.indexOf(this.props.Document);
@@ -233,6 +242,28 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         e.stopPropagation();
     }
 
+    @action
+    recordPause = (e: React.MouseEvent) => {
+        this._pauseStart = new Date().getTime();
+        this._paused = true;
+        this._recorder.pause();
+        e.stopPropagation();
+
+    }
+
+    @action
+    recordPlay = (e: React.MouseEvent) => {
+        this._pauseEnd = new Date().getTime();
+        this._paused = false;
+        this._recorder.resume();
+        e.stopPropagation();
+
+    }
+
+    @computed get pauseTime() {
+        return (this._pauseEnd - this._pauseStart);
+    }
+
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -241,14 +272,28 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                     <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" ? "red" : "black" }}>
+                    {/* <button className={`audiobox-record${interactive}`} style={{ backgroundColor: this.audioState === "recording" ? "lightgrey" : "black" }}>
                         {this.audioState === "recording" ?
-                            <div className="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>
+                                <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}>
+                                <FontAwesomeIcon style={{ width: "100%" }} icon={"stop"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
+                            </div>
+                            <div className="buttons" onClick={this._paused ? this.recordPlay : this.recordPause}>
+                                <FontAwesomeIcon style={{ width: "100%" }} icon={this._paused ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
+                            </div>
+                            <div className="time">{NumCast(this.layoutDoc.currentTimecode).toFixed(1)}</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-player" >
-- 
cgit v1.2.3-70-g09d2


From 2b516f94110069a2df8daf6a52f03db7bb498789 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sat, 11 Jul 2020 15:45:48 -0700
Subject: make documents

---
 package.json                         |  2 +-
 src/client/views/nodes/AudioBox.scss | 27 +++++++++++++
 src/client/views/nodes/AudioBox.tsx  | 78 +++++++++++++++++++++++++++++++++---
 3 files changed, 100 insertions(+), 7 deletions(-)

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

diff --git a/package.json b/package.json
index 62a554355..5a6c6f0b1 100644
--- a/package.json
+++ b/package.json
@@ -249,4 +249,4 @@
         "xoauth2": "^1.2.0",
         "xregexp": "^4.3.0"
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 06498182d..b1da40287 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -196,6 +196,33 @@
                     }
                 }
 
+                .audiobox-marker-container1,
+                .audiobox-marker-minicontainer {
+                    position: absolute;
+                    width: 10px;
+                    height: 90%;
+                    top: 2.5%;
+                    background: gray;
+                    border-radius: 5px;
+                    box-shadow: black 2px 2px 1px;
+                    opacity: 0.3;
+
+                    .audiobox-marker {
+                        position: relative;
+                        height: calc(100% - 15px);
+                        margin-top: 15px;
+                    }
+
+                    .audio-marker:hover {
+                        border: orange 2px solid;
+                    }
+                }
+
+                .audiobox-marker-container1:hover,
+                .audiobox-marker-minicontainer:hover {
+                    opacity: 1;
+                }
+
                 .audiobox-marker-minicontainer {
                     width: 5px;
                     border-radius: 1px;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index cb56ae203..9a2baf85d 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -2,13 +2,13 @@ import React = require("react");
 import { FieldViewProps, FieldView } from './FieldView';
 import { observer } from "mobx-react";
 import "./AudioBox.scss";
-import { Cast, DateCast, NumCast } from "../../../fields/Types";
+import { Cast, DateCast, NumCast, FieldValue } from "../../../fields/Types";
 import { AudioField, nullAudio } from "../../../fields/URLField";
 import { ViewBoxBaseComponent } from "../DocComponent";
 import { makeInterface, createSchema } from "../../../fields/Schema";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
-import { runInAction, observable, reaction, IReactionDisposer, computed, action } from "mobx";
+import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace } from "mobx";
 import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Doc, DocListCast } from "../../../fields/Doc";
@@ -21,6 +21,9 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { ComputedField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
+import { FormattedTextBox } from "./formattedText/FormattedTextBox";
+import { RichTextField } from "../../../fields/RichTextField";
+
 
 // testing testing 
 
@@ -54,7 +57,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _pauseEnd = 0;
     _pausedTime = 0;
     _stream: MediaStream | undefined;
+    _start: number = 0;
+    _hold: boolean = false;
 
+    @observable private _duration = 0;
+    @observable private _rect: Array<any> = []
+    @observable private _markers: Array<any> = [];
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
     @observable private _repeat: boolean = false;
@@ -122,7 +130,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     playFromTime = (absoluteTime: number) => {
         this.recordingStart && this.playFrom((absoluteTime - this.recordingStart) / 1000);
     }
-    playFrom = (seekTimeInSeconds: number) => {
+
+    @action
+    playFrom = (seekTimeInSeconds: number, endTime: number = this.dataDoc.duration) => {
+        let play;
+        clearTimeout(play);
+        this._duration = endTime - seekTimeInSeconds;
         if (this._ele && AudioBox.Enabled) {
             if (seekTimeInSeconds < 0) {
                 if (seekTimeInSeconds > -1) {
@@ -131,9 +144,13 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                     this.pause();
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
+                console.log("playing");
                 this._ele.currentTime = seekTimeInSeconds;
                 this._ele.play();
                 runInAction(() => this.audioState = "playing");
+                if (endTime !== this.dataDoc.duration) {
+                    play = setTimeout(() => this.pause(), (this._duration) * 1000);
+                }
             } else {
                 this.pause();
             }
@@ -264,6 +281,25 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         return (this._pauseEnd - this._pauseStart);
     }
 
+    @action
+    newMarker(marker: number) {
+        this._markers.push(marker);
+    }
+
+    start(marker: number) {
+        console.log("start!");
+        this._hold = true;
+        this._start = marker;
+    }
+
+    @action
+    end(marker: number) {
+        console.log("end!");
+        this._hold = false;
+        this._markers.push([this._start, marker]);
+        this._start = 0;
+    }
+
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -304,12 +340,40 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                             onPointerDown={e => {
                                 if (e.button === 0 && !e.ctrlKey) {
                                     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();
-                                    e.stopPropagation();
+
+                                }
+                                if (e.button === 0 && e.altKey) {
+                                    this.newMarker(this._ele!.currentTime);
+                                }
+
+                                if (e.button === 0 && e.shiftKey) {
+                                    const rect = (e.target as any).getBoundingClientRect();
+                                    this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+                                    this._hold ? this.end(this._ele!.currentTime) : this.start(this._ele!.currentTime);
                                 }
-                            }} >
+                            }}>
+                            {this._markers.map((m, i) => {
+                                let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
+                                let rect;
+                                (m.length > 1) ?
+
+                                    rect =
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} key={i} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); e.stopPropagation() }}>
+                                        {/* <FormattedTextBox {...this.props} key={"label" + i} Document={text} /> */}
+                                    </div>
+                                    :
+                                    rect =
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${m / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+                                        {/* <DocumentView {...this.props}
+                                            Document={text}
+                                            parentActive={returnTrue} /> */}
+                                    </div>;
+                                return rect
+                            })}
                             {DocListCast(this.dataDoc.links).map((l, i) => {
                                 let la1 = l.anchor1 as Doc;
                                 let la2 = l.anchor2 as Doc;
@@ -319,8 +383,10 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                     la2 = l.anchor1 as Doc;
                                     linkTime = NumCast(l.anchor1_timecode);
                                 }
+
+
                                 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}%` }}>
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(this.dataDoc.duration - linkTime) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
                                         <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
                                             <DocumentView {...this.props}
                                                 Document={l}
-- 
cgit v1.2.3-70-g09d2


From 07eb07f394765e56898a21570849a01ab3c54304 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 12 Jul 2020 19:25:53 -0700
Subject: added change markers and formatted time and added resizer

---
 src/client/views/nodes/AudioBox.scss     | 27 ++++++++-
 src/client/views/nodes/AudioBox.tsx      | 96 +++++++++++++++++++++++++++++++-
 src/client/views/nodes/AudioResizer.scss | 11 ++++
 src/client/views/nodes/AudioResizer.tsx  | 48 ++++++++++++++++
 4 files changed, 178 insertions(+), 4 deletions(-)
 create mode 100644 src/client/views/nodes/AudioResizer.scss
 create mode 100644 src/client/views/nodes/AudioResizer.tsx

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index b1da40287..8eb92f126 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -118,7 +118,7 @@
 
             .audiobox-timeline {
                 position: relative;
-                height: 100%;
+                height: 80%;
                 width: 100%;
                 background: white;
                 border: gray solid 1px;
@@ -184,6 +184,8 @@
                     background: gray;
                     border-radius: 5px;
                     box-shadow: black 2px 2px 1px;
+                    resize: horizontal;
+                    overflow: auto;
 
                     .audiobox-marker {
                         position: relative;
@@ -216,6 +218,15 @@
                     .audio-marker:hover {
                         border: orange 2px solid;
                     }
+
+                    .resizer {
+                        position: absolute;
+                        right: 0;
+                        cursor: ew-resize;
+                        height: 100%;
+                        width: 1px;
+                        z-index: 100;
+                    }
                 }
 
                 .audiobox-marker-container1:hover,
@@ -234,6 +245,20 @@
                     }
                 }
             }
+
+            .current-time {
+                position: absolute;
+                font-size: 12;
+                top: 70%;
+                left: 23%;
+            }
+
+            .total-time {
+                position: absolute;
+                left: 80%;
+                top: 70%;
+                font-size: 12;
+            }
         }
     }
 }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 9a2baf85d..4dbcf7497 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -23,6 +23,7 @@ import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 import { RichTextField } from "../../../fields/RichTextField";
+import { AudioResizer } from "./AudioResizer";
 
 
 // testing testing 
@@ -60,6 +61,9 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _start: number = 0;
     _hold: boolean = false;
 
+    private _isPointerDown = false;
+    private _currMarker: any;
+
     @observable private _duration = 0;
     @observable private _rect: Array<any> = []
     @observable private _markers: Array<any> = [];
@@ -300,6 +304,85 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._start = 0;
     }
 
+    onPointerDown = (e: React.PointerEvent, m: any): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isPointerDown = true;
+        console.log("click");
+        this._currMarker = m;
+
+        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;
+
+        const rect = (e.target as any).getBoundingClientRect();
+        this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+
+        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("audiobox-marker-container1");
+
+        const rect = (e.target as any).getBoundingClientRect();
+        // let newWidth = parseFloat(`${(e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration)}%`);
+
+        // if (resize) {
+        //     console.log(parseFloat(resize.style.width));
+        //     console.log(newWidth);
+        //     console.log(e.movementX);
+        //     if (e.movementX < 0) {
+        //         resize.style.width = `${parseFloat(resize.style.width) - (newWidth)}%`;
+        //     } else {
+        //         resize.style.width = `${parseFloat(resize.style.width) + (newWidth)}%`;
+        //     }
+        // }
+
+        let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+
+        this.changeMarker(this._currMarker, newTime);
+    }
+
+    @action
+    changeMarker = (m: any, time: any) => {
+        for (let i = 0; i < this._markers.length; i++) {
+            if (this.isSame(this._markers[i], m)) {
+                this._markers[i][1] = time;
+            }
+        }
+    }
+
+    isSame = (m1: any, m2: any) => {
+        if (m1[0] == m2[0] && m1[1] == m2[1]) {
+            return true;
+        }
+        return false;
+    }
+
+    formatTime = (time: number) => {
+        let hours = Math.floor(time / 60 / 60);
+        let minutes = Math.floor(time / 60) - (hours * 60);
+        let seconds = time % 60;
+
+        return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
+    }
+
     render() {
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
@@ -357,13 +440,14 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                 }
                             }}>
                             {this._markers.map((m, i) => {
-                                let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
+                                // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
                                 (m.length > 1) ?
 
                                     rect =
-                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} key={i} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); e.stopPropagation() }}>
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} key={i} id={"audiobox-marker-container1"} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); e.stopPropagation() }} >
                                         {/* <FormattedTextBox {...this.props} key={"label" + i} Document={text} /> */}
+                                        <div className="resizer" onPointerDown={e => this.onPointerDown(e, m)}></div>
                                     </div>
                                     :
                                     rect =
@@ -372,7 +456,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                             Document={text}
                                             parentActive={returnTrue} /> */}
                                     </div>;
-                                return rect
+                                return rect;
                             })}
                             {DocListCast(this.dataDoc.links).map((l, i) => {
                                 let la1 = l.anchor1 as Doc;
@@ -408,6 +492,12 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                             <div className="audiobox-current" style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
                             {this.audio}
                         </div>
+                        <div className="current-time">
+                            {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+                        </div>
+                        <div className="total-time">
+                            {this.formatTime(Math.round(NumCast(this.layoutDoc.duration)))}
+                        </div>
                     </div>
                 </div>
             }
diff --git a/src/client/views/nodes/AudioResizer.scss b/src/client/views/nodes/AudioResizer.scss
new file mode 100644
index 000000000..892ad21e7
--- /dev/null
+++ b/src/client/views/nodes/AudioResizer.scss
@@ -0,0 +1,11 @@
+.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
new file mode 100644
index 000000000..f9ab8353f
--- /dev/null
+++ b/src/client/views/nodes/AudioResizer.tsx
@@ -0,0 +1,48 @@
+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
-- 
cgit v1.2.3-70-g09d2


From 1c6a596aec0a3bf933af03a754e2bf0f268e3d51 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 16 Jul 2020 08:58:45 -0700
Subject: fixed resize flicker, fixed double click, added resizer on left,
 added move to new row

---
 src/client/views/nodes/AudioBox.scss |  43 +++++++++++----
 src/client/views/nodes/AudioBox.tsx  | 100 ++++++++++++++++++++++++-----------
 2 files changed, 100 insertions(+), 43 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 8eb92f126..4a6a471ec 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -54,10 +54,11 @@
         margin-top: auto;
         margin-bottom: auto;
         width: 100%;
-        height: 80%;
+        height: 100%;
         position: relative;
         padding-right: 5px;
         display: flex;
+        background-color: red;      
 
         .time {
             position: relative;
@@ -65,6 +66,7 @@
             width: 100%;
             font-size: 20;
             text-align: center;
+            top: 5;
         }
 
         .buttons {
@@ -76,7 +78,7 @@
         }
 
         .buttons:hover {
-            background-color: darkgrey;
+            background-color: crimson;
         }
     }
 
@@ -86,7 +88,7 @@
         position: relative;
         display: flex;
         padding-left: 2px;
-        background: lightgrey;
+        background: black;
 
         .audiobox-player {
             margin-top: auto;
@@ -97,20 +99,28 @@
             padding-right: 5px;
             display: flex;
 
-            .audiobox-playhead,
-            .audiobox-dictation {
+            .audiobox-playhead {
                 position: relative;
                 margin-top: auto;
                 margin-bottom: auto;
-                width: 25px;
+                margin-right: 2px;
+                width: 30px;
+                height: 25px;
                 padding: 2px;
+                border-radius: 50%;
+                background-color: dimgrey;
             }
 
             .audiobox-playhead:hover {
-                background-color: darkgrey;
+                background-color: white;
             }
 
             .audiobox-dictation {
+                position: relative;
+                margin-top: auto;
+                margin-bottom: auto;
+                width: 25px;
+                padding: 2px;
                 align-items: center;
                 display: inherit;
                 background: dimgray;
@@ -123,6 +133,7 @@
                 background: white;
                 border: gray solid 1px;
                 border-radius: 3px;
+                z-index: 1000;
 
                 .audiobox-current {
                     width: 1px;
@@ -184,7 +195,6 @@
                     background: gray;
                     border-radius: 5px;
                     box-shadow: black 2px 2px 1px;
-                    resize: horizontal;
                     overflow: auto;
 
                     .audiobox-marker {
@@ -224,7 +234,16 @@
                         right: 0;
                         cursor: ew-resize;
                         height: 100%;
-                        width: 1px;
+                        width: 2px;
+                        z-index: 100;
+                    }
+
+                    .left-resizer {
+                        position: absolute;
+                        left: 0;
+                        cursor: ew-resize;
+                        height: 100%;
+                        width: 2px;
                         z-index: 100;
                     }
                 }
@@ -250,14 +269,16 @@
                 position: absolute;
                 font-size: 12;
                 top: 70%;
-                left: 23%;
+                left: 30px;
+                color: white;
             }
 
             .total-time {
                 position: absolute;
-                left: 80%;
                 top: 70%;
                 font-size: 12;
+                right: 2px;
+                color: white;
             }
         }
     }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 4dbcf7497..a4e7b0899 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -60,10 +60,13 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _stream: MediaStream | undefined;
     _start: number = 0;
     _hold: boolean = false;
+    _left: boolean = false;
+    _amount: number = 1;
 
     private _isPointerDown = false;
     private _currMarker: any;
 
+    @observable private _dragging: boolean = false;
     @observable private _duration = 0;
     @observable private _rect: Array<any> = []
     @observable private _markers: Array<any> = [];
@@ -288,6 +291,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     @action
     newMarker(marker: number) {
         this._markers.push(marker);
+        this._amount++;
     }
 
     start(marker: number) {
@@ -302,14 +306,19 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._hold = false;
         this._markers.push([this._start, marker]);
         this._start = 0;
+        this._amount++;
     }
 
-    onPointerDown = (e: React.PointerEvent, m: any): void => {
+    onPointerDown = (e: React.PointerEvent, m: any, left: boolean): void => {
         e.stopPropagation();
         e.preventDefault();
         this._isPointerDown = true;
         console.log("click");
         this._currMarker = m;
+        let targetele = document.getElementById("timeline");
+        targetele?.setPointerCapture(e.pointerId);
+        this._left = left;
+
 
         document.removeEventListener("pointermove", this.onPointerMove);
         document.addEventListener("pointermove", this.onPointerMove);
@@ -317,19 +326,24 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         document.addEventListener("pointerup", this.onPointerUp);
     }
 
+    @action
     onPointerUp = (e: PointerEvent): void => {
         e.stopPropagation();
         e.preventDefault();
         this._isPointerDown = false;
+        this._dragging = false;
 
         const rect = (e.target as any).getBoundingClientRect();
         this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
+        let targetele = document.getElementById("timeline");
+        targetele?.releasePointerCapture(e.pointerId);
+
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
     }
 
-    onPointerMove = (e: PointerEvent): void => {
+    onPointerMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
         console.log("drag");
@@ -338,32 +352,21 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
             return;
         }
 
-        // let resize = document.getElementById("audiobox-marker-container1");
+        const rect = await (e.target as any).getBoundingClientRect();
 
-        const rect = (e.target as any).getBoundingClientRect();
-        // let newWidth = parseFloat(`${(e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration)}%`);
-
-        // if (resize) {
-        //     console.log(parseFloat(resize.style.width));
-        //     console.log(newWidth);
-        //     console.log(e.movementX);
-        //     if (e.movementX < 0) {
-        //         resize.style.width = `${parseFloat(resize.style.width) - (newWidth)}%`;
-        //     } else {
-        //         resize.style.width = `${parseFloat(resize.style.width) + (newWidth)}%`;
-        //     }
-        // }
+        // if (e.target as HTMLElement === document.getElementById("timeline")) {
 
         let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
-
+        console.log(newTime);
         this.changeMarker(this._currMarker, newTime);
+        // }
     }
 
     @action
     changeMarker = (m: any, time: any) => {
         for (let i = 0; i < this._markers.length; i++) {
             if (this.isSame(this._markers[i], m)) {
-                this._markers[i][1] = time;
+                this._left ? this._markers[i][0] = time : this._markers[i][1] = time;
             }
         }
     }
@@ -383,7 +386,32 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');
     }
 
+    @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!");
+    }
+
+    // see if time is encapsulated by comparing time on both sides (for moving onto a new row in the timeline for the markers)
+
     render() {
+        trace();
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
@@ -406,7 +434,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                             <div className="buttons" onClick={this._paused ? this.recordPlay : this.recordPause}>
                                 <FontAwesomeIcon style={{ width: "100%" }} icon={this._paused ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
                             </div>
-                            <div className="time">{NumCast(this.layoutDoc.currentTimecode).toFixed(1)}</div>
+                            <div className="time">{this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}</div>
                         </div>
 
                         :
@@ -415,19 +443,24 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                             </button>}
                 </div> :
                 <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
+                    <div className="background">
+                    </div>
                     <div className="audiobox-player" >
-                        <div className="audiobox-playhead" onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%" }} icon={this.audioState === "paused" ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></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" onClick={e => e.stopPropagation()}
+                        <div className="audiobox-playhead" title={this.audioState === "paused" ? "play" : "pause"} onClick={this.onPlay}> <FontAwesomeIcon style={{ width: "100%", position: "absolute", left: "0px", top: "5px" }} 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" id="timeline" onClick={e => { e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change}
                             onPointerDown={e => {
+                                e.stopPropagation();
+                                e.preventDefault();
                                 if (e.button === 0 && !e.ctrlKey) {
                                     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();
-
+                                    if (e.target as HTMLElement !== document.getElementById("current")) {
+                                        const wasPaused = this.audioState === "paused";
+                                        this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+                                        wasPaused && this.pause();
+                                    }
                                 }
                                 if (e.button === 0 && e.altKey) {
                                     this.newMarker(this._ele!.currentTime);
@@ -442,12 +475,14 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                             {this._markers.map((m, i) => {
                                 // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
+                                console.log(1 / this._amount * 100);
                                 (m.length > 1) ?
 
                                     rect =
-                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} key={i} id={"audiobox-marker-container1"} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); e.stopPropagation() }} >
-                                        {/* <FormattedTextBox {...this.props} key={"label" + i} Document={text} /> */}
-                                        <div className="resizer" onPointerDown={e => this.onPointerDown(e, m)}></div>
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${this.formatTime(Math.round(m[0]))}` + " - " + `${this.formatTime(Math.round(m[1]))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / this._amount * 100}%`, top: `${i * 1 / this._amount * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); e.stopPropagation() }} >
+                                        {/* <FormattedTextBox {...this.props} key={"label" + i} /> */}
+                                        <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
+                                        <div className="resizer" onPointerDown={e => this.onPointerDown(e, m, false)}></div>
                                     </div>
                                     :
                                     rect =
@@ -470,7 +505,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
 
 
                                 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}%`, width: `${(this.dataDoc.duration - linkTime) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
                                         <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
                                             <DocumentView {...this.props}
                                                 Document={l}
@@ -489,8 +524,9 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                             onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); wasPaused && this.pause(); e.stopPropagation(); } }} />
                                     </div>;
                             })}
-                            <div className="audiobox-current" style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
+                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
                             {this.audio}
+
                         </div>
                         <div className="current-time">
                             {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
-- 
cgit v1.2.3-70-g09d2


From 5dcc72c2c61e3aafc30b041e312784d881de72d8 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Wed, 22 Jul 2020 20:54:40 -0700
Subject: turn markers into documents and kind of got linking to work

---
 src/client/documents/Documents.ts    |   3 +
 src/client/views/nodes/AudioBox.scss |   8 +--
 src/client/views/nodes/AudioBox.tsx  | 119 +++++++++++++++++++++++++++--------
 src/fields/documentSchemas.ts        |   4 ++
 4 files changed, 105 insertions(+), 29 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 8e7d125b0..b94670cd5 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -189,6 +189,9 @@ export interface DocumentOptions {
     searchQuery?: string; // for queryBox
     filterQuery?: string;
     linearViewIsExpanded?: boolean; // is linear view expanded
+    isLabel?: boolean;         // whether the document is a label or not (video / audio)
+    audioStart?: number;       // the time frame where the audio should begin playing
+    audioEnd?: number;         // the time frame where the audio should stop playing  
 }
 
 class EmptyBox {
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 4a6a471ec..6601c6f24 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -190,10 +190,10 @@
                 .audiobox-marker-minicontainer {
                     position: absolute;
                     width: 10px;
-                    height: 90%;
+                    height: 10px;
                     top: 2.5%;
                     background: gray;
-                    border-radius: 5px;
+                    border-radius: 50%;
                     box-shadow: black 2px 2px 1px;
                     overflow: auto;
 
@@ -268,14 +268,14 @@
             .current-time {
                 position: absolute;
                 font-size: 12;
-                top: 70%;
+                top: calc(100% - 10px);
                 left: 30px;
                 color: white;
             }
 
             .total-time {
                 position: absolute;
-                top: 70%;
+                top: calc(100% - 10px);
                 font-size: 12;
                 right: 2px;
                 color: white;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index a4e7b0899..5863c8789 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -2,13 +2,13 @@ import React = require("react");
 import { FieldViewProps, FieldView } from './FieldView';
 import { observer } from "mobx-react";
 import "./AudioBox.scss";
-import { Cast, DateCast, NumCast, FieldValue } from "../../../fields/Types";
+import { Cast, DateCast, NumCast, FieldValue, ScriptCast } from "../../../fields/Types";
 import { AudioField, nullAudio } from "../../../fields/URLField";
-import { ViewBoxBaseComponent } from "../DocComponent";
+import { ViewBoxBaseComponent, ViewBoxAnnotatableComponent } from "../DocComponent";
 import { makeInterface, createSchema } from "../../../fields/Schema";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
-import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace } from "mobx";
+import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace, toJS } from "mobx";
 import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Doc, DocListCast } from "../../../fields/Doc";
@@ -18,12 +18,16 @@ import { Id } from "../../../fields/FieldSymbols";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { DocumentView } from "./DocumentView";
 import { Docs, DocUtils } from "../../documents/Documents";
-import { ComputedField } from "../../../fields/ScriptField";
+import { ComputedField, ScriptField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 import { RichTextField } from "../../../fields/RichTextField";
 import { AudioResizer } from "./AudioResizer";
+import { List } from "../../../fields/List";
+import { LabelBox } from "./LabelBox";
+import { Transform } from "../../util/Transform";
+import { Scripting } from "../../util/Scripting";
 
 
 // testing testing 
@@ -44,10 +48,12 @@ type AudioDocument = makeInterface<[typeof documentSchema, typeof audioSchema]>;
 const AudioDocument = makeInterface(documentSchema, audioSchema);
 
 @observer
-export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument>(AudioDocument) {
+export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioDocument>(AudioDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(AudioBox, fieldKey); }
     public static Enabled = false;
 
+    static Instance: AudioBox;
+
     _linkPlayDisposer: IReactionDisposer | undefined;
     _reactionDisposer: IReactionDisposer | undefined;
     _scrubbingDisposer: IReactionDisposer | undefined;
@@ -68,7 +74,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
 
     @observable private _dragging: boolean = false;
     @observable private _duration = 0;
-    @observable private _rect: Array<any> = []
+    @observable private _rect: Array<any> = [];
     @observable private _markers: Array<any> = [];
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
@@ -86,6 +92,9 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._scrubbingDisposer?.();
     }
     componentDidMount() {
+        if (!this.dataDoc.markerAmount) {
+            this.dataDoc.markerAmount = 0;
+        }
         runInAction(() => this.audioState = this.path ? "paused" : undefined);
         this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID,
             scrollLinkId => {
@@ -289,8 +298,15 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     }
 
     @action
-    newMarker(marker: number) {
+    newMarker(marker: Doc) {
         this._markers.push(marker);
+        if (this.dataDoc.markers) {
+            this.dataDoc.markers.push(marker);
+        } else {
+            this.dataDoc.markers = new List<Doc>(this._markers)
+        }
+
+        console.log(this.dataDoc.markers)
         this._amount++;
     }
 
@@ -304,7 +320,13 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     end(marker: number) {
         console.log("end!");
         this._hold = false;
-        this._markers.push([this._start, marker]);
+        //this._markers.push(Docs.Create.LabelDocument({ isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }))
+        if (this.dataDoc[this.annotationKey]) {
+            this.dataDoc[this.annotationKey].push(Docs.Create.LabelDocument({ title: "hi", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
+        } else {
+            this.dataDoc[this.annotationKey] = new List<Doc>([Docs.Create.LabelDocument({ title: "hi", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })]);
+        }
+
         this._start = 0;
         this._amount++;
     }
@@ -315,7 +337,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         this._isPointerDown = true;
         console.log("click");
         this._currMarker = m;
-        let targetele = document.getElementById("timeline");
+        const targetele = document.getElementById("timeline");
         targetele?.setPointerCapture(e.pointerId);
         this._left = left;
 
@@ -336,7 +358,7 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         const rect = (e.target as any).getBoundingClientRect();
         this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
-        let targetele = document.getElementById("timeline");
+        const targetele = document.getElementById("timeline");
         targetele?.releasePointerCapture(e.pointerId);
 
         document.removeEventListener("pointermove", this.onPointerMove);
@@ -357,31 +379,57 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
         // if (e.target as HTMLElement === document.getElementById("timeline")) {
 
         let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
-        console.log(newTime);
+
         this.changeMarker(this._currMarker, newTime);
         // }
     }
 
     @action
     changeMarker = (m: any, time: any) => {
-        for (let i = 0; i < this._markers.length; i++) {
-            if (this.isSame(this._markers[i], m)) {
-                this._left ? this._markers[i][0] = time : this._markers[i][1] = time;
+        for (let i = 0; i < this.dataDoc.markers.length; i++) {
+            if (this.isSame(this.dataDoc.markers[i], m)) {
+                // this._left ? this._markers[i][0] = time : this._markers[i][1] = time;
+                this._left ? this.dataDoc.markers[i].audioStart = time : this.dataDoc.markers[i].audioEnd = time;
             }
         }
     }
 
     isSame = (m1: any, m2: any) => {
-        if (m1[0] == m2[0] && m1[1] == m2[1]) {
+        if (m1.audioStart === m2.audioStart && m1.audioEnd === m2.audioEnd) {
             return true;
         }
         return false;
     }
 
+    @action
+    isOverlap = (m: any, i: number) => {
+        let counter = 0;
+        let check = [];
+
+        if (i == 0) {
+            this._markers = [];
+        }
+        for (let marker of this._markers) {
+            if ((m.audioEnd > marker.audioStart && m.audioStart < marker.audioEnd)) {
+                counter++;
+                check.push(marker)
+            }
+        }
+
+
+        if (this.dataDoc.markerAmount < counter) {
+            this.dataDoc.markerAmount = counter;
+        }
+
+        this._markers.push(m);
+
+        return counter;
+    }
+
     formatTime = (time: number) => {
-        let hours = Math.floor(time / 60 / 60);
-        let minutes = Math.floor(time / 60) - (hours * 60);
-        let seconds = time % 60;
+        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');
     }
@@ -463,7 +511,8 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                     }
                                 }
                                 if (e.button === 0 && e.altKey) {
-                                    this.newMarker(this._ele!.currentTime);
+
+                                    this.newMarker(Docs.Create.TextDocument("", { isLabel: true, audioStart: this._ele!.currentTime }));
                                 }
 
                                 if (e.button === 0 && e.shiftKey) {
@@ -472,21 +521,39 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
                                     this._hold ? this.end(this._ele!.currentTime) : this.start(this._ele!.currentTime);
                                 }
                             }}>
-                            {this._markers.map((m, i) => {
+                            {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
+
                                 // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
-                                console.log(1 / this._amount * 100);
-                                (m.length > 1) ?
+
+                                (!m.isLabel) ?
 
                                     rect =
-                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${this.formatTime(Math.round(m[0]))}` + " - " + `${this.formatTime(Math.round(m[1]))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${m[0] / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(m[1] - m[0]) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / this._amount * 100}%`, top: `${i * 1 / this._amount * 100}%` }} onClick={e => { this.playFrom(m[0], m[1]); 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 + 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() }} >
                                         {/* <FormattedTextBox {...this.props} key={"label" + i} /> */}
                                         <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
+                                        <DocumentView {...this.props}
+                                            Document={m}
+                                            pointerEvents={true}
+                                            NativeHeight={returnZero}
+                                            NativeWidth={returnZero}
+                                            rootSelected={returnFalse}
+                                            LayoutTemplate={undefined}
+                                            ContainingCollectionDoc={this.props.Document}
+                                            dontRegisterView={true}
+                                            removeDocument={undefined}
+                                            parentActive={returnTrue}
+                                            onClick={() => ScriptCast(ScriptField.MakeScript("this.playFrom((NumCast(m.audioStart), NumCast(m.audioEnd)))"))}
+                                            ignoreAutoHeight={false}
+                                            ScreenToLocalTransform={Transform.Identity}
+                                            bringToFront={emptyFunction}
+                                            backgroundColor={returnTransparent} />
+                                        {/* <LabelBox {... this.props} Document={m} /> */}
                                         <div className="resizer" onPointerDown={e => this.onPointerDown(e, m, false)}></div>
                                     </div>
                                     :
                                     rect =
-                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${m / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
                                         {/* <DocumentView {...this.props}
                                             Document={text}
                                             parentActive={returnTrue} /> */}
@@ -539,4 +606,6 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
             }
         </div>;
     }
-}
\ No newline at end of file
+}
+
+Scripting.addGlobal(function playFrom(start: number, end: number) { return AudioBox.Instance.playFrom(start, end); })
\ No newline at end of file
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index ddffb56c3..c77d80d76 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -19,6 +19,10 @@ export const documentSchema = createSchema({
     currentTimecode: "number",  // current play back time of a temporal document (video / audio)
     displayTimecode: "number",  // the time that a document should be displayed (e.g., time an annotation should be displayed on a video)
     inOverlay: "boolean",       // whether the document is rendered in an OverlayView which handles selection/dragging differently
+    isLabel: "boolean",         // whether the document is a label or not (video / audio)
+    audioStart: "number",       // the time frame where the audio should begin playing
+    audioEnd: "number",         // the time frame where the audio should stop playing
+    markers: listSpec(Doc),     // list of markers for audio / video
     x: "number",                // x coordinate when in a freeform view 
     y: "number",                // y coordinate when in a freeform view 
     z: "number",                // z "coordinate" - non-zero specifies the overlay layer of a freeformview
-- 
cgit v1.2.3-70-g09d2


From a8ccd648f811a5049bda15d5ace9d44ef570b418 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 23 Jul 2020 14:54:55 -0700
Subject: change onClick and link kind of works

---
 src/client/views/nodes/AudioBox.scss    | 14 +++--
 src/client/views/nodes/AudioBox.tsx     | 92 ++++++++++++++++++++-------------
 src/client/views/nodes/DocumentView.tsx |  2 +
 3 files changed, 69 insertions(+), 39 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 6601c6f24..ff3f78457 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -152,7 +152,6 @@
                     background: gray;
                     border-radius: 100%;
                     opacity: 0.9;
-                    background-color: transparent;
                     box-shadow: black 2px 2px 1px;
 
                     .linkAnchorBox-cont {
@@ -199,8 +198,10 @@
 
                     .audiobox-marker {
                         position: relative;
-                        height: calc(100% - 15px);
-                        margin-top: 15px;
+                        height: 100%;
+                        // height: calc(100% - 15px);
+                        width: 100%;
+                        //margin-top: 15px;
                     }
 
                     .audio-marker:hover {
@@ -238,6 +239,13 @@
                         z-index: 100;
                     }
 
+                    .click {
+                        position: relative;
+                        height: 100%;
+                        width: 100%;
+                        z-index: 100;
+                    }
+
                     .left-resizer {
                         position: absolute;
                         left: 0;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 5863c8789..fefb05d06 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -53,6 +53,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     public static Enabled = false;
 
     static Instance: AudioBox;
+    static Script: ScriptField;
 
     _linkPlayDisposer: IReactionDisposer | undefined;
     _reactionDisposer: IReactionDisposer | undefined;
@@ -86,6 +87,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); }
     async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); }
 
+
+    constructor(props: Readonly<FieldViewProps>) {
+        super(props);
+        if (!AudioBox.Script) {
+            AudioBox.Script = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!;
+        }
+    }
+
     componentWillUnmount() {
         this._reactionDisposer?.();
         this._linkPlayDisposer?.();
@@ -95,6 +104,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         if (!this.dataDoc.markerAmount) {
             this.dataDoc.markerAmount = 0;
         }
+
         runInAction(() => this.audioState = this.path ? "paused" : undefined);
         this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID,
             scrollLinkId => {
@@ -299,15 +309,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     @action
     newMarker(marker: Doc) {
-        this._markers.push(marker);
-        if (this.dataDoc.markers) {
-            this.dataDoc.markers.push(marker);
+        if (this.dataDoc[this.annotationKey]) {
+            this.dataDoc[this.annotationKey].push(marker);
         } else {
-            this.dataDoc.markers = new List<Doc>(this._markers)
+            this.dataDoc[this.annotationKey] = new List<Doc>([marker]);
         }
-
-        console.log(this.dataDoc.markers)
-        this._amount++;
     }
 
     start(marker: number) {
@@ -322,9 +328,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._hold = false;
         //this._markers.push(Docs.Create.LabelDocument({ isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }))
         if (this.dataDoc[this.annotationKey]) {
-            this.dataDoc[this.annotationKey].push(Docs.Create.LabelDocument({ title: "hi", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
+            this.dataDoc[this.annotationKey].push(Docs.Create.LabelDocument({ title: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })); // onClick: ScriptField.MakeScript(`playFrom(${NumCast(this._start)}, ${NumCast(marker)})`)
         } else {
-            this.dataDoc[this.annotationKey] = new List<Doc>([Docs.Create.LabelDocument({ title: "hi", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })]);
+            this.dataDoc[this.annotationKey] = new List<Doc>([Docs.Create.LabelDocument({ title: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })]);
         }
 
         this._start = 0;
@@ -386,10 +392,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     @action
     changeMarker = (m: any, time: any) => {
-        for (let i = 0; i < this.dataDoc.markers.length; i++) {
-            if (this.isSame(this.dataDoc.markers[i], m)) {
+        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.markers[i].audioStart = time : this.dataDoc.markers[i].audioEnd = time;
+                this._left ? this.dataDoc[this.annotationKey][i].audioStart = time : this.dataDoc[this.annotationKey][i].audioEnd = time;
             }
         }
     }
@@ -456,6 +462,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         console.log("double!");
     }
 
+    script = () => AudioBox.Script;
+
     // see if time is encapsulated by comparing time on both sides (for moving onto a new row in the timeline for the markers)
 
     render() {
@@ -512,7 +520,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 }
                                 if (e.button === 0 && e.altKey) {
 
-                                    this.newMarker(Docs.Create.TextDocument("", { isLabel: true, audioStart: this._ele!.currentTime }));
+                                    this.newMarker(Docs.Create.LabelDocument({ title: "", isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
                                 }
 
                                 if (e.button === 0 && e.shiftKey) {
@@ -543,20 +551,32 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             dontRegisterView={true}
                                             removeDocument={undefined}
                                             parentActive={returnTrue}
-                                            onClick={() => ScriptCast(ScriptField.MakeScript("this.playFrom((NumCast(m.audioStart), NumCast(m.audioEnd)))"))}
+                                            onClick={this.script}
                                             ignoreAutoHeight={false}
-                                            ScreenToLocalTransform={Transform.Identity}
                                             bringToFront={emptyFunction}
-                                            backgroundColor={returnTransparent} />
+                                            backgroundColor={returnTransparent}
+                                            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>
                                     :
                                     rect =
                                     <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
-                                        {/* <DocumentView {...this.props}
-                                            Document={text}
-                                            parentActive={returnTrue} /> */}
+                                        <DocumentView {...this.props}
+                                            Document={m}
+                                            pointerEvents={true}
+                                            NativeHeight={returnZero}
+                                            NativeWidth={returnZero}
+                                            rootSelected={returnFalse}
+                                            LayoutTemplate={undefined}
+                                            ContainingCollectionDoc={this.props.Document}
+                                            dontRegisterView={true}
+                                            removeDocument={undefined}
+                                            parentActive={returnTrue}
+                                            onClick={undefined}
+                                            ignoreAutoHeight={false}
+                                            bringToFront={emptyFunction} />
                                     </div>;
                                 return rect;
                             })}
@@ -572,23 +592,23 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
 
                                 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}%` }}>
-                                        <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
-                                            <DocumentView {...this.props}
-                                                Document={l}
-                                                NativeHeight={returnZero}
-                                                NativeWidth={returnZero}
-                                                rootSelected={returnFalse}
-                                                LayoutTemplate={undefined}
-                                                LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
-                                                ContainingCollectionDoc={this.props.Document}
-                                                dontRegisterView={true}
-                                                parentActive={returnTrue}
-                                                bringToFront={emptyFunction}
-                                                backgroundColor={returnTransparent} />
-                                        </div>
+                                    <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}
+                                            NativeWidth={returnZero}
+                                            rootSelected={returnFalse}
+                                            LayoutTemplate={undefined}
+                                            LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
+                                            ContainingCollectionDoc={this.props.Document}
+                                            dontRegisterView={true}
+                                            parentActive={returnTrue}
+                                            bringToFront={emptyFunction}
+                                            backgroundColor={returnTransparent} />
+                                        {/* </div> */}
                                         <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
-                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); wasPaused && this.pause(); e.stopPropagation(); } }} />
+                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); wasPaused && this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
                                     </div>;
                             })}
                             <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
@@ -608,4 +628,4 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     }
 }
 
-Scripting.addGlobal(function playFrom(start: number, end: number) { return AudioBox.Instance.playFrom(start, end); })
\ No newline at end of file
+// Scripting.addGlobal(function playFrom(audioDoc: Doc, start: number, end: number) { return audioDoc.playFrom(start, end); })
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 748938699..641dd782b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -100,6 +100,7 @@ export interface DocumentViewProps {
     layoutKey?: string;
     radialMenu?: String[];
     display?: string;
+    scriptContext?: any;
 }
 
 @observer
@@ -322,6 +323,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 const func = () => this.onClickHandler.script.run({
                     this: this.layoutDoc,
                     self: this.rootDoc,
+                    scriptContext: this.props.scriptContext,
                     thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey
                 }, console.log);
                 if (this.props.Document !== Doc.UserDoc()["dockedBtn-undo"] && this.props.Document !== Doc.UserDoc()["dockedBtn-redo"]) {
-- 
cgit v1.2.3-70-g09d2


From 1a3d12ea7a107df9bd4fd32b1db00eb558e93a21 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sat, 25 Jul 2020 18:15:33 -0700
Subject: fix bugs

---
 src/client/views/nodes/AudioBox.scss |  1 +
 src/client/views/nodes/AudioBox.tsx  | 79 ++++++++++++++++++++++++++----------
 2 files changed, 59 insertions(+), 21 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index ff3f78457..7b0e50e60 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -195,6 +195,7 @@
                     border-radius: 50%;
                     box-shadow: black 2px 2px 1px;
                     overflow: auto;
+                    cursor: pointer;
 
                     .audiobox-marker {
                         position: relative;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index fefb05d06..bfa48578b 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -28,6 +28,7 @@ import { List } from "../../../fields/List";
 import { LabelBox } from "./LabelBox";
 import { Transform } from "../../util/Transform";
 import { Scripting } from "../../util/Scripting";
+import { ColorBox } from "./ColorBox";
 
 
 // testing testing 
@@ -53,7 +54,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     public static Enabled = false;
 
     static Instance: AudioBox;
-    static Script: ScriptField;
+    static RangeScript: ScriptField;
+    static LabelScript: ScriptField;
 
     _linkPlayDisposer: IReactionDisposer | undefined;
     _reactionDisposer: IReactionDisposer | undefined;
@@ -69,6 +71,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _hold: boolean = false;
     _left: boolean = false;
     _amount: number = 1;
+    _markers: Array<any> = [];
 
     private _isPointerDown = false;
     private _currMarker: any;
@@ -76,7 +79,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @observable private _dragging: boolean = false;
     @observable private _duration = 0;
     @observable private _rect: Array<any> = [];
-    @observable private _markers: Array<any> = [];
+
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
     @observable private _repeat: boolean = false;
@@ -90,9 +93,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     constructor(props: Readonly<FieldViewProps>) {
         super(props);
-        if (!AudioBox.Script) {
-            AudioBox.Script = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!;
+        if (!AudioBox.RangeScript) {
+            AudioBox.RangeScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!;
+        }
+
+        if (!AudioBox.LabelScript) {
+            AudioBox.LabelScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!;
         }
+
+
     }
 
     componentWillUnmount() {
@@ -167,6 +176,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (seekTimeInSeconds > -1) {
                     setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000);
                 } else {
+                    console.log("dude");
                     this.pause();
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
@@ -327,12 +337,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         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: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
+
         if (this.dataDoc[this.annotationKey]) {
-            this.dataDoc[this.annotationKey].push(Docs.Create.LabelDocument({ title: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })); // onClick: ScriptField.MakeScript(`playFrom(${NumCast(this._start)}, ${NumCast(marker)})`)
+            this.dataDoc[this.annotationKey].push(newMarker); // onClick: ScriptField.MakeScript(`playFrom(${NumCast(this._start)}, ${NumCast(marker)})`)
         } else {
-            this.dataDoc[this.annotationKey] = new List<Doc>([Docs.Create.LabelDocument({ title: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })]);
+            this.dataDoc[this.annotationKey] = new List<Doc>([newMarker]);
         }
 
+
         this._start = 0;
         this._amount++;
     }
@@ -407,21 +420,21 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return false;
     }
 
-    @action
     isOverlap = (m: any, i: number) => {
+        console.log("called");
         let counter = 0;
-        let check = [];
 
         if (i == 0) {
             this._markers = [];
         }
-        for (let marker of this._markers) {
-            if ((m.audioEnd > marker.audioStart && m.audioStart < marker.audioEnd)) {
+        for (let i = 0; i < this._markers.length; i++) {
+            if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) {
                 counter++;
-                check.push(marker)
+                console.log(counter);
             }
         }
-
+        console.log(counter);
+        console.log(this.dataDoc.markerAmount);
 
         if (this.dataDoc.markerAmount < counter) {
             this.dataDoc.markerAmount = counter;
@@ -432,6 +445,29 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return counter;
     }
 
+    // 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
+
+    //     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
+    // }
+
     formatTime = (time: number) => {
         const hours = Math.floor(time / 60 / 60);
         const minutes = Math.floor(time / 60) - (hours * 60);
@@ -462,7 +498,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         console.log("double!");
     }
 
-    script = () => AudioBox.Script;
+    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)
 
@@ -533,12 +571,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
                                 // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
-
                                 (!m.isLabel) ?
 
                                     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() }} >
-                                        {/* <FormattedTextBox {...this.props} key={"label" + i} /> */}
                                         <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
                                         <DocumentView {...this.props}
                                             Document={m}
@@ -551,10 +587,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             dontRegisterView={true}
                                             removeDocument={undefined}
                                             parentActive={returnTrue}
-                                            onClick={this.script}
+                                            onClick={this.rangeScript}
                                             ignoreAutoHeight={false}
                                             bringToFront={emptyFunction}
-                                            backgroundColor={returnTransparent}
                                             scriptContext={this} />
                                         {/* <LabelBox {... this.props} Document={m} /> */}
                                         {/* <div className="click" onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}></div> */}
@@ -574,13 +609,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             dontRegisterView={true}
                                             removeDocument={undefined}
                                             parentActive={returnTrue}
-                                            onClick={undefined}
+                                            onClick={this.labelScript}
                                             ignoreAutoHeight={false}
-                                            bringToFront={emptyFunction} />
+                                            bringToFront={emptyFunction}
+                                            scriptContext={this} />
                                     </div>;
                                 return rect;
                             })}
                             {DocListCast(this.dataDoc.links).map((l, i) => {
+                                console.log("hi");
                                 let la1 = l.anchor1 as Doc;
                                 let la2 = l.anchor2 as Doc;
                                 let linkTime = NumCast(l.anchor2_timecode);
@@ -608,10 +645,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             backgroundColor={returnTransparent} />
                                         {/* </div> */}
                                         <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
-                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); wasPaused && this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
+                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
                                     </div>;
                             })}
-                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
+                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); console.log("hi"); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
                             {this.audio}
 
                         </div>
-- 
cgit v1.2.3-70-g09d2


From 8722fe67029f76f572eacd6e02d623690ca94793 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sun, 26 Jul 2020 22:08:13 -0700
Subject: added options to hide markers/labels

---
 src/client/documents/Documents.ts   |   1 +
 src/client/views/nodes/AudioBox.tsx | 110 ++++++++++++++++++++----------------
 src/fields/ScriptField.ts           |   1 -
 3 files changed, 62 insertions(+), 50 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 170426db3..ffc22292e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -562,6 +562,7 @@ export namespace Docs {
 
             viewDoc.author = Doc.CurrentUserEmail;
             viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc);
+            console.log("audio link!");
 
             return Doc.assign(viewDoc, delegateProps, true);
         }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index bfa48578b..0cab0fc61 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -176,7 +176,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (seekTimeInSeconds > -1) {
                     setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000);
                 } else {
-                    console.log("dude");
                     this.pause();
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
@@ -227,7 +226,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
         funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" });
-
+        funcs.push({ description: (this.layoutDoc.hideMarkers ? "Don't hide" : "Hide") + " markers", event: () => this.layoutDoc.hideMarkers = !this.layoutDoc.hideMarkers, icon: "expand-arrows-alt" })
+        funcs.push({ description: (this.layoutDoc.hideLabels ? "Don't hide" : "Hide") + " labels", event: () => this.layoutDoc.hideLabels = !this.layoutDoc.hideLabels, icon: "expand-arrows-alt" })
+        funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" })
         ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
@@ -433,8 +434,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 console.log(counter);
             }
         }
-        console.log(counter);
-        console.log(this.dataDoc.markerAmount);
 
         if (this.dataDoc.markerAmount < counter) {
             this.dataDoc.markerAmount = counter;
@@ -503,9 +502,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     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;
+        }
+    }
 
     render() {
-        trace();
+        //trace();
         const interactive = this.active() ? "-interactive" : "";
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
@@ -568,56 +572,56 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 }
                             }}>
                             {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
-
                                 // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
                                 (!m.isLabel) ?
-
-                                    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="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
-                                        <DocumentView {...this.props}
-                                            Document={m}
-                                            pointerEvents={true}
-                                            NativeHeight={returnZero}
-                                            NativeWidth={returnZero}
-                                            rootSelected={returnFalse}
-                                            LayoutTemplate={undefined}
-                                            ContainingCollectionDoc={this.props.Document}
-                                            dontRegisterView={true}
-                                            removeDocument={undefined}
-                                            parentActive={returnTrue}
-                                            onClick={this.rangeScript}
-                                            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>
+                                    (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="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
+                                            <DocumentView {...this.props}
+                                                Document={m}
+                                                pointerEvents={true}
+                                                NativeHeight={returnZero}
+                                                NativeWidth={returnZero}
+                                                rootSelected={returnFalse}
+                                                LayoutTemplate={undefined}
+                                                ContainingCollectionDoc={this.props.Document}
+                                                dontRegisterView={true}
+                                                removeDocument={undefined}
+                                                parentActive={returnTrue}
+                                                onClick={this.layoutDoc.playOnClick ? this.rangeScript : undefined}
+                                                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>
                                     :
-                                    rect =
-                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
-                                        <DocumentView {...this.props}
-                                            Document={m}
-                                            pointerEvents={true}
-                                            NativeHeight={returnZero}
-                                            NativeWidth={returnZero}
-                                            rootSelected={returnFalse}
-                                            LayoutTemplate={undefined}
-                                            ContainingCollectionDoc={this.props.Document}
-                                            dontRegisterView={true}
-                                            removeDocument={undefined}
-                                            parentActive={returnTrue}
-                                            onClick={this.labelScript}
-                                            ignoreAutoHeight={false}
-                                            bringToFront={emptyFunction}
-                                            scriptContext={this} />
-                                    </div>;
+                                    (this.layoutDoc.hideLabels) ? (null) :
+                                        rect =
+                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+                                            <DocumentView {...this.props}
+                                                Document={m}
+                                                pointerEvents={true}
+                                                NativeHeight={returnZero}
+                                                NativeWidth={returnZero}
+                                                rootSelected={returnFalse}
+                                                LayoutTemplate={undefined}
+                                                ContainingCollectionDoc={this.props.Document}
+                                                dontRegisterView={true}
+                                                removeDocument={undefined}
+                                                parentActive={returnTrue}
+                                                onClick={this.layoutDoc.playOnClick ? this.labelScript : undefined}
+                                                ignoreAutoHeight={false}
+                                                bringToFront={emptyFunction}
+                                                scriptContext={this} />
+                                        </div>;
                                 return rect;
                             })}
                             {DocListCast(this.dataDoc.links).map((l, i) => {
-                                console.log("hi");
+
                                 let la1 = l.anchor1 as Doc;
                                 let la2 = l.anchor2 as Doc;
                                 let linkTime = NumCast(l.anchor2_timecode);
@@ -627,6 +631,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     linkTime = NumCast(l.anchor1_timecode);
                                 }
 
+                                if (la1.audioStart) {
+                                    linkTime = NumCast(la1.audioStart);
+                                }
+
+                                if (la2.audioStart) {
+                                    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()}>
@@ -648,7 +660,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
                                     </div>;
                             })}
-                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); console.log("hi"); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
+                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
                             {this.audio}
 
                         </div>
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 4604a2132..bd08b2f32 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -53,7 +53,6 @@ async function deserializeScript(script: ScriptField) {
     if (script.script.originalScript === 'convertToButtons(dragData)') {
         return (script as any).script = (ScriptField.ConvertToButtons ?? (ScriptField.ConvertToButtons = ComputedField.MakeFunction('convertToButtons(dragData)', { dragData: "DocumentDragData" })))?.script;
     }
-    console.log(script.script.originalScript);
     const captures: ProxyField<Doc> = (script as any).captures;
     if (captures) {
         const doc = (await captures.value())!;
-- 
cgit v1.2.3-70-g09d2


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

---
 src/client/views/nodes/AudioBox.scss               |  2 +-
 src/client/views/nodes/AudioBox.tsx                | 34 ++++++++++++++++++----
 .../views/nodes/formattedText/FormattedTextBox.tsx | 24 +++++++++++++++
 3 files changed, 54 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 7b0e50e60..6d52988bb 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -194,7 +194,7 @@
                     background: gray;
                     border-radius: 50%;
                     box-shadow: black 2px 2px 1px;
-                    overflow: auto;
+                    overflow: visible;
                     cursor: pointer;
 
                     .audiobox-marker {
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 0cab0fc61..02932baac 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -72,6 +72,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _left: boolean = false;
     _amount: number = 1;
     _markers: Array<any> = [];
+    _first: boolean = false;
 
     private _isPointerDown = false;
     private _currMarker: any;
@@ -128,6 +129,22 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
                 const sel = selected.length ? selected[0].props.Document : undefined;
+                // if (sel) {
+                //     DocListCast(sel.links).map((l, i) => {
+                //         let la1 = l.anchor1 as Doc;
+                //         let la2 = l.anchor2 as Doc;
+                //         let linkTime = NumCast(l.anchor2_timecode);
+                //         if (Doc.AreProtosEqual(la1, this.dataDoc)) {
+                //             la1 = l.anchor2 as Doc;
+                //             la2 = l.anchor1 as Doc;
+                //             linkTime = NumCast(l.anchor1_timecode);
+                //         }
+                //         console.log(linkTime);
+                //         if (linkTime) {
+                //             this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(linkTime);
+                //         }
+                //     });
+                // }
                 this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
                 this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
             });
@@ -186,7 +203,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (endTime !== this.dataDoc.duration) {
                     play = setTimeout(() => this.pause(), (this._duration) * 1000);
                 }
-            } else {
+            } else { // this is getting called because time is greater than duration
                 this.pause();
             }
         }
@@ -226,9 +243,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
         funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" });
-        funcs.push({ description: (this.layoutDoc.hideMarkers ? "Don't hide" : "Hide") + " markers", event: () => this.layoutDoc.hideMarkers = !this.layoutDoc.hideMarkers, icon: "expand-arrows-alt" })
-        funcs.push({ description: (this.layoutDoc.hideLabels ? "Don't hide" : "Hide") + " labels", event: () => this.layoutDoc.hideLabels = !this.layoutDoc.hideLabels, icon: "expand-arrows-alt" })
-        funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" })
+        funcs.push({ description: (this.layoutDoc.hideMarkers ? "Don't hide" : "Hide") + " markers", event: () => this.layoutDoc.hideMarkers = !this.layoutDoc.hideMarkers, icon: "expand-arrows-alt" });
+        funcs.push({ description: (this.layoutDoc.hideLabels ? "Don't hide" : "Hide") + " labels", event: () => this.layoutDoc.hideLabels = !this.layoutDoc.hideLabels, icon: "expand-arrows-alt" });
+        funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" });
         ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
@@ -421,12 +438,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return false;
     }
 
+    // Probably need a better way to format
     isOverlap = (m: any, i: number) => {
         console.log("called");
         let counter = 0;
 
-        if (i == 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)) {
@@ -508,9 +527,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         }
     }
 
+    reset = () => {
+        this._first = true;
+    }
+
     render() {
         //trace();
         const interactive = this.active() ? "-interactive" : "";
+        this.reset();
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
                 <div className="audiobox-buttons">
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 28ab7ecd633e92619adfcbd1ce3ca72ddbba7ea8 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 29 Jul 2020 01:05:43 -0400
Subject: fixed up dot anchors on audio labels/anchors

---
 src/client/documents/Documents.ts                  |  5 ++++-
 .../CollectionFreeFormLinkView.tsx                 |  6 +++---
 src/client/views/nodes/AudioBox.tsx                | 25 +++++++++-------------
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/LinkAnchorBox.tsx           |  2 +-
 src/client/views/nodes/formattedText/marks_rts.ts  |  6 +++---
 6 files changed, 22 insertions(+), 24 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fb9f6fe46..122383744 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -192,6 +192,7 @@ export interface DocumentOptions {
     filterQuery?: string;
     linearViewIsExpanded?: boolean; // is linear view expanded
     isLabel?: boolean;         // whether the document is a label or not (video / audio)
+    useLinkSmallAnchor?: boolean;  // whether links to this document should use a miniature linkAnchorBox
     audioStart?: number;       // the time frame where the audio should begin playing
     audioEnd?: number;         // the time frame where the audio should stop playing  
 }
@@ -627,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);
+            const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { hideLinkButton: true, useLinkSmallAnchor: true, ...options });
             Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'");
             return instance;
         }
@@ -925,6 +926,8 @@ export namespace DocUtils {
         if (target.doc === Doc.UserDoc()) return undefined;
 
         const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id);
+        Doc.GetProto(linkDoc)["anchor1-useLinkSmallAnchor"] = source.doc.useLinkSmallAnchor;
+        Doc.GetProto(linkDoc)["anchor2-useLinkSmallAnchor"] = target.doc.useLinkSmallAnchor;
         linkDoc.linkDisplay = true;
         linkDoc.hidden = true;
         linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index bfe569853..3a2979696 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -54,15 +54,15 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
                 const bfield = afield === "anchor1" ? "anchor2" : "anchor1";
 
                 // really hacky stuff to make the LinkAnchorBox display where we want it to:
-                //   if there's an element in the DOM with a classname containing the link's id and a targetids attribute containing the other end of the link, 
+                //   if there's an element in the DOM with a classname containing the link's id and a data-targetids attribute containing the other end of the link, 
                 //   then that DOM element is a hyperlink source for the current anchor and we want to place our link box at it's top right
                 //   otherwise, we just use the computed nearest point on the document boundary to the target Document
                 const linkId = this.props.LinkDocs[0][Id]; // this link's Id
                 const AanchorId = (this.props.LinkDocs[0][afield] as Doc)[Id]; // anchor a's id
                 const BanchorId = (this.props.LinkDocs[0][bfield] as Doc)[Id]; // anchor b's id
                 const linkEles = Array.from(window.document.getElementsByClassName(linkId));
-                const targetAhyperlink = linkEles.find((ele: any) => ele.getAttribute("targetids")?.includes(AanchorId));
-                const targetBhyperlink = linkEles.find((ele: any) => ele.getAttribute("targetids")?.includes(BanchorId));
+                const targetAhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes(AanchorId));
+                const targetBhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes(BanchorId));
                 if (!targetBhyperlink) {
                     this.props.A.rootDoc[afield + "_x"] = (apt.point.x - abounds.left) / abounds.width * 100;
                     this.props.A.rootDoc[afield + "_y"] = (apt.point.y - abounds.top) / abounds.height * 100;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 02932baac..34f87fc10 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -355,7 +355,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         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: "", isLabel: false, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
+        let newMarker = Docs.Create.LabelDocument({ title: "", isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
 
         if (this.dataDoc[this.annotationKey]) {
             this.dataDoc[this.annotationKey].push(newMarker); // onClick: ScriptField.MakeScript(`playFrom(${NumCast(this._start)}, ${NumCast(marker)})`)
@@ -586,7 +586,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 }
                                 if (e.button === 0 && e.altKey) {
 
-                                    this.newMarker(Docs.Create.LabelDocument({ title: "", isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
+                                    this.newMarker(Docs.Create.LabelDocument({ title: "", useLinkSmallAnchor: true, hideLinkButton: true, isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
                                 }
 
                                 if (e.button === 0 && e.shiftKey) {
@@ -611,7 +611,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                                 rootSelected={returnFalse}
                                                 LayoutTemplate={undefined}
                                                 ContainingCollectionDoc={this.props.Document}
-                                                dontRegisterView={true}
                                                 removeDocument={undefined}
                                                 parentActive={returnTrue}
                                                 onClick={this.layoutDoc.playOnClick ? this.rangeScript : undefined}
@@ -634,7 +633,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                                 rootSelected={returnFalse}
                                                 LayoutTemplate={undefined}
                                                 ContainingCollectionDoc={this.props.Document}
-                                                dontRegisterView={true}
                                                 removeDocument={undefined}
                                                 parentActive={returnTrue}
                                                 onClick={this.layoutDoc.playOnClick ? this.labelScript : undefined}
@@ -655,15 +653,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     linkTime = NumCast(l.anchor1_timecode);
                                 }
 
-                                if (la1.audioStart) {
-                                    linkTime = NumCast(la1.audioStart);
-                                }
-
                                 if (la2.audioStart) {
                                     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}> */}
@@ -672,15 +665,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             NativeHeight={returnZero}
                                             NativeWidth={returnZero}
                                             rootSelected={returnFalse}
-                                            LayoutTemplate={undefined}
-                                            LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
                                             ContainingCollectionDoc={this.props.Document}
-                                            dontRegisterView={true}
                                             parentActive={returnTrue}
                                             bringToFront={emptyFunction}
-                                            backgroundColor={returnTransparent} />
-                                        {/* </div> */}
-                                        <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
+                                            backgroundColor={returnTransparent}
+                                            ContentScaling={returnOne}
+                                            forcedBackgroundColor={returnTransparent}
+                                            pointerEvents={false}
+                                            LayoutTemplate={undefined}
+                                            LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
+                                        />
+                                        <div key={i} className={`audiobox-marker`} onPointerEnter={() => Doc.linkFollowHighlight(la1)}
                                             onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
                                     </div>;
                             })}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 74634f837..77932d58e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1098,7 +1098,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots
             this.layoutDoc.presBox ||  // presentationbox nodes
             this.props.dontRegisterView ? (null) : // view that are not registered
-            DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
+            DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink(d)).map((d, i) =>
                 <DocumentView {...this.props} key={i + 1}
                     Document={d}
                     ContainingCollectionView={this.props.ContainingCollectionView}
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index d4ab70200..2fc002b9e 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -120,7 +120,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
         const y = NumCast(this.rootDoc[this.fieldKey + "_y"], 100);
         const c = StrCast(this.layoutDoc._backgroundColor, StrCast(this.layoutDoc.backgroundColor, StrCast(this.dataDoc.backgroundColor, "lightBlue"))); // note this is not where the typical lightBlue default color comes from.  See Documents.Create.LinkDocument()
         const anchor = this.fieldKey === "anchor1" ? "anchor2" : "anchor1";
-        const anchorScale = (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .25;
+        const anchorScale = !this.dataDoc[this.fieldKey + "-useLinkSmallAnchor"] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .25;
 
         const timecode = this.dataDoc[anchor + "_timecode"];
         const targetTitle = StrCast((this.dataDoc[anchor] as Doc)?.title) + (timecode !== undefined ? ":" + timecode : "");
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index f95f46104..2ce61ab58 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -31,7 +31,7 @@ export const marks: { [index: string]: MarkSpec } = {
         inclusive: false,
         parseDOM: [{
             tag: "a[href]", getAttrs(dom: any) {
-                return { allLinks: [{ href: dom.getAttribute("href"), title: dom.getAttribute("title"), linkId: dom.getAttribute("linkids"), targetId: dom.getAttribute("targetids") }], location: dom.getAttribute("location"), };
+                return { allLinks: [{ href: dom.getAttribute("href"), title: dom.getAttribute("title"), linkId: dom.getAttribute("linkids"), targetId: dom.dataset.targetids }], location: dom.getAttribute("location"), };
             }
         }],
         toDOM(node: any) {
@@ -40,10 +40,10 @@ export const marks: { [index: string]: MarkSpec } = {
             return node.attrs.docref && node.attrs.title ?
                 ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, href: node.attrs.allLinks[0].href, class: "prosemirror-attribution" }, node.attrs.title], ["br"]] :
                 node.attrs.allLinks.length === 1 ?
-                    ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}`, href: node.attrs.allLinks[0].href }, 0] :
+                    ["a", { ...node.attrs, class: linkids, dataTargetids: targetids, title: `${node.attrs.title}`, href: node.attrs.allLinks[0].href }, 0] :
                     ["div", { class: "prosemirror-anchor" },
                         ["span", { class: "prosemirror-linkBtn" },
-                            ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}` }, 0],
+                            ["a", { ...node.attrs, class: linkids, dataTargetids: targetids, title: `${node.attrs.title}` }, 0],
                             ["input", { class: "prosemirror-hrefoptions" }],
                         ],
                         ["div", { class: "prosemirror-links" }, ...node.attrs.allLinks.map((item: { href: string, title: string }) =>
-- 
cgit v1.2.3-70-g09d2


From 58f75d38dcfd113c90e4e27e55468d06412c653e Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Sat, 1 Aug 2020 16:34:48 -0700
Subject: fixed bugs and added waveform (need fix)

---
 package-lock.json                    | 36 ++++++++++++++
 package.json                         |  2 +
 src/client/documents/Documents.ts    |  2 +-
 src/client/views/nodes/AudioBox.scss | 10 +++-
 src/client/views/nodes/AudioBox.tsx  | 91 +++++++++++++++++++++++++++++++++++-
 src/typings/index.d.ts               |  1 +
 6 files changed, 139 insertions(+), 3 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 698bd60cc..31369f427 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2198,6 +2198,37 @@
             "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
             "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
         },
+        "axios": {
+            "version": "0.19.2",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+            "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+            "requires": {
+                "follow-redirects": "1.5.10"
+            },
+            "dependencies": {
+                "debug": {
+                    "version": "3.1.0",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+                    "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+                    "requires": {
+                        "ms": "2.0.0"
+                    }
+                },
+                "follow-redirects": {
+                    "version": "1.5.10",
+                    "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+                    "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+                    "requires": {
+                        "debug": "=3.1.0"
+                    }
+                },
+                "ms": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+                }
+            }
+        },
         "babel-code-frame": {
             "version": "6.26.0",
             "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -14119,6 +14150,11 @@
                 "prop-types": "^15.6.2"
             }
         },
+        "react-audio-waveform": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/react-audio-waveform/-/react-audio-waveform-0.0.5.tgz",
+            "integrity": "sha512-4dJwhl+LQRuywzmmjuhWT5GueT3Ai2ZhB+loVxg0sRdhplyDp96xAu10/V/+J25Cl7YqNtl2DWSxvSoI/i6l6w=="
+        },
         "react-autosuggest": {
             "version": "9.4.3",
             "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz",
diff --git a/package.json b/package.json
index 6c466825e..44304ce87 100644
--- a/package.json
+++ b/package.json
@@ -131,6 +131,7 @@
         "archiver": "^3.1.1",
         "array-batcher": "^1.2.3",
         "async": "^2.6.2",
+        "axios": "^0.19.2",
         "babel-runtime": "^6.26.0",
         "bcrypt-nodejs": "0.0.3",
         "bezier-curve": "^1.0.0",
@@ -216,6 +217,7 @@
         "raw-loader": "^1.0.0",
         "rc-switch": "^1.9.0",
         "react": "^16.12.0",
+        "react-audio-waveform": "0.0.5",
         "react-autosuggest": "^9.4.3",
         "react-color": "^2.18.1",
         "react-compound-slider": "^2.5.0",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 122383744..88f470576 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)), { hideLinkButton: true, useLinkSmallAnchor: true, ...options });
+            const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { ...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 6d52988bb..35ab5da8b 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -140,6 +140,14 @@
                     height: 100%;
                     background-color: red;
                     position: absolute;
+                    top: 0px;
+                }
+
+                .waveform {
+                    position: relative;
+                    width: 100%;
+                    height: 100%;
+                    overflow: hidden;
                 }
 
                 .audiobox-linker,
@@ -259,7 +267,7 @@
 
                 .audiobox-marker-container1:hover,
                 .audiobox-marker-minicontainer:hover {
-                    opacity: 1;
+                    opacity: 0.8;
                 }
 
                 .audiobox-marker-minicontainer {
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 34f87fc10..3d1932883 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -29,7 +29,8 @@ import { LabelBox } from "./LabelBox";
 import { Transform } from "../../util/Transform";
 import { Scripting } from "../../util/Scripting";
 import { ColorBox } from "./ColorBox";
-
+import Waveform from "react-audio-waveform"
+import axios from "axios"
 
 // testing testing 
 
@@ -73,6 +74,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _amount: number = 1;
     _markers: Array<any> = [];
     _first: boolean = false;
+    _buckets: Array<number> = new Array();
 
     private _isPointerDown = false;
     private _currMarker: any;
@@ -80,6 +82,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @observable private _dragging: boolean = false;
     @observable private _duration = 0;
     @observable private _rect: Array<any> = [];
+    // @observable private _buckets: Array<number> = new Array();
 
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
@@ -299,6 +302,81 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return path === nullAudio ? "" : path;
     }
 
+    @action
+    buckets = async () => {
+        let audioCtx = new (window.AudioContext)();
+        const buckets: number[] = [];
+
+        axios({ url: this.path, responseType: "arraybuffer" })
+            .then(async response => {
+                let audioData = response.data;
+
+                await 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);
+                        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();
+    }
+
     @computed get audio() {
         const interactive = this.active() ? "-interactive" : "";
         return <audio ref={this.setRef} className={`audiobox-control${interactive}`}>
@@ -595,6 +673,17 @@ 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" }}>
+                                {console.log(this.peaks)}
+                                <Waveform
+                                    color={"#000000"}
+                                    height={20}
+                                    barWidth={0.1}
+                                    pos={this.layoutDoc.currentTimecode}
+                                    duration={this.layoutDoc.duration}
+                                    peaks={this._buckets.length === 100 ? this._buckets : undefined}
+                                    progressColor={"#0000ff"} />
+                            </div>
                             {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
                                 // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false });
                                 let rect;
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index 452882e09..ee2c25f8a 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -7,6 +7,7 @@ declare module 'cors';
 declare module 'webrtc-adapter';
 declare module 'bezier-curve';
 declare module 'fit-curve'
+declare module 'react-audio-waveform'
 
 
 declare module '@react-pdf/renderer' {
-- 
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/AudioBox.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 2f12e2d6945c51eb7df961443fe5d06b10577659 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Wed, 5 Aug 2020 01:00:39 -0700
Subject: change css

---
 src/client/views/nodes/AudioBox.scss | 26 +++++++---
 src/client/views/nodes/AudioBox.tsx  | 98 +++++++++++++++++++++++++++---------
 2 files changed, 95 insertions(+), 29 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 0ea4b37cb..9065966d7 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -90,6 +90,16 @@
         padding-left: 2px;
         background: black;
 
+        .audiobox-dictation {
+            position: absolute;
+            width: 30px;
+            height: 100%;
+            align-items: center;
+            display: inherit;
+            background: dimgray;
+            left: 0px;
+        }
+
         .audiobox-player {
             margin-top: auto;
             margin-bottom: auto;
@@ -108,11 +118,15 @@
                 height: 25px;
                 padding: 2px;
                 border-radius: 50%;
-                background-color: dimgrey;
+                background-color: black;
+                color: white;
             }
 
             .audiobox-playhead:hover {
-                background-color: white;
+                // background-color:  black;
+                // border-radius: 5px;
+                background-color: grey;
+                color: lightgrey;
             }
 
             .audiobox-dictation {
@@ -285,16 +299,16 @@
 
             .current-time {
                 position: absolute;
-                font-size: 12;
-                top: calc(100% - 10px);
+                font-size: 8;
+                top: calc(100% - 8px);
                 left: 30px;
                 color: white;
             }
 
             .total-time {
                 position: absolute;
-                top: calc(100% - 10px);
-                font-size: 12;
+                top: calc(100% - 8px);
+                font-size: 8;
                 right: 2px;
                 color: white;
             }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 7c90547ef..0f142261d 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -74,7 +74,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _amount: number = 1;
     _markers: Array<any> = [];
     _first: boolean = false;
-    _buckets: Array<number> = new Array();
+    _buckets: Array<number> = new Array<number>();
     _count: Array<any> = [];
 
     private _isPointerDown = false;
@@ -133,24 +133,45 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
                 const sel = selected.length ? selected[0].props.Document : undefined;
-                // if (sel) {
-                //     DocListCast(sel.links).map((l, i) => {
-                //         let la1 = l.anchor1 as Doc;
-                //         let la2 = l.anchor2 as Doc;
-                //         let linkTime = NumCast(l.anchor2_timecode);
-                //         if (Doc.AreProtosEqual(la1, this.dataDoc)) {
-                //             la1 = l.anchor2 as Doc;
-                //             la2 = l.anchor1 as Doc;
-                //             linkTime = NumCast(l.anchor1_timecode);
-                //         }
-                //         console.log(linkTime);
-                //         if (linkTime) {
-                //             this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(linkTime);
-                //         }
-                //     });
-                // }
-                this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
-                this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
+                let link;
+                if (sel) {
+                    DocListCast(sel.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.audioStart) {
+                            linkTime = NumCast(la1.audioStart);
+                        }
+
+                        if (la1.audioEnd) {
+                            endTime = NumCast(la1.audioEnd);
+                        }
+
+                        if (la2.audioEnd) {
+                            endTime = NumCast(la2.audioEnd);
+                        }
+
+                        console.log(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);
+                        }
+                    });
+                }
+                if (!link) {
+                    this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
+                    this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
+                }
             });
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime));
     }
@@ -303,6 +324,38 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         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)();
@@ -555,7 +608,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         if (this._first) {
             this._first = false;
             this.markers();
-            console.log(this._count);
         }
 
 
@@ -672,10 +724,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             </button>}
                 </div> :
                 <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
-                    <div className="background">
-                    </div>
+                    <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" }} icon={this.audioState === "paused" ? "play" : "pause"} size={"1x"} /></div>
+                        <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" id="timeline" onClick={e => { e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change}
@@ -711,6 +762,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     pos={this.layoutDoc.currentTimecode}
                                     duration={this.dataDoc.duration}
                                     peaks={this._buckets.length === 100 ? this._buckets : undefined}
+
                                     progressColor={"#0000ff"} />
                             </div>
                             {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
-- 
cgit v1.2.3-70-g09d2


From 4062563cdc4606d9513ab7f9d0524e92a6e90305 Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Wed, 5 Aug 2020 04:08:01 -0700
Subject: made waveform resizable (still have progress bar bug)

---
 src/client/views/nodes/AudioBox.scss |  4 +-
 src/client/views/nodes/AudioBox.tsx  | 90 ++++++++++++++++++++++++++++++++++--
 src/typings/index.d.ts               |  4 +-
 webpack.config.js                    | 62 ++++++++++++-------------
 4 files changed, 122 insertions(+), 38 deletions(-)

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

diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 9065966d7..306062ced 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -148,6 +148,7 @@
                 border: gray solid 1px;
                 border-radius: 3px;
                 z-index: 1000;
+                overflow: hidden;
 
                 .audiobox-current {
                     width: 1px;
@@ -162,7 +163,8 @@
                     width: 100%;
                     height: 100%;
                     overflow: hidden;
-                    z-index: 0;
+                    z-index: -1000;
+                    bottom: -30%;
                 }
 
                 .audiobox-linker,
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 0f142261d..682aaaeed 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -80,6 +80,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     private _isPointerDown = false;
     private _currMarker: any;
 
+    @observable private _height: number = NumCast(this.layoutDoc.height);
+    @observable private _finish: boolean = false;
     @observable private _dragging: boolean = false;
     @observable private _duration = 0;
     @observable private _rect: Array<any> = [];
@@ -686,14 +688,92 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @computed get height() {
         console.log(this.layoutDoc._height);
         if (this.layoutDoc._height) {
-            return 0.8 * 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");
+    //     }
+    // }
+
+    @computed get waveform() {
+        return <Waveform
+            color={"blue"}
+            height={this._height}
+            barWidth={0.1}
+            pos={this.layoutDoc.currentTimecode}
+            duration={this.dataDoc.duration}
+            peaks={this._buckets.length === 100 ? this._buckets : undefined}
+            progressColor={"blue"} />;
+    }
+
+    @action
+    update = () => {
+        if (this.layoutDoc._height) {
+            this._height = 0.8 * NumCast(this.layoutDoc._height);
+            console.log(document.getElementById("timeline")?.clientWidth);
+            let width = document.getElementById("timeline")?.clientWidth;
+            let canvas2 = document.getElementsByTagName("canvas")[0];
+            if (canvas2) {
+                let oldWidth = canvas2.width;
+                let 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');
+                if (context) {
+                    context.scale(ratio1, ratio2)
+                }
+            }
+
+            let canvas1 = document.getElementsByTagName("canvas")[1];
+            if (canvas1) {
+                let oldWidth = canvas1.width;
+                let 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');
+                if (context) {
+                    context.scale(ratio1, ratio2)
+
+                }
+            }
+        }
+    }
+
+
     render() {
         //trace();
         const interactive = this.active() ? "-interactive" : "";
         this.reset();
+        this.update();
+        // this.waveform();
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
                 <div className="audiobox-buttons">
@@ -755,15 +835,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             }}>
                             <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
                                 {console.log(this.peaks)}
-                                <Waveform
+                                {/* <Waveform
                                     color={"#000000"}
-                                    height={this.height}
+                                    height={this._height}
                                     barWidth={0.1}
                                     pos={this.layoutDoc.currentTimecode}
                                     duration={this.dataDoc.duration}
                                     peaks={this._buckets.length === 100 ? this._buckets : undefined}
 
-                                    progressColor={"#0000ff"} />
+                                    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 });
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index ee2c25f8a..728dd51d3 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -6,8 +6,8 @@ declare module 'cors';
 
 declare module 'webrtc-adapter';
 declare module 'bezier-curve';
-declare module 'fit-curve'
-declare module 'react-audio-waveform'
+declare module 'fit-curve';
+declare module 'react-audio-waveform';
 
 
 declare module '@react-pdf/renderer' {
diff --git a/webpack.config.js b/webpack.config.js
index a5fe6ad80..c973be1ed 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -66,42 +66,42 @@ module.exports = {
     },
     module: {
         rules: [{
-                test: [/\.tsx?$/],
-                use: [{
-                    loader: 'ts-loader',
-                    options: {
-                        transpileOnly: true
-                    }
-                }]
+            test: [/\.tsx?$/],
+            use: [{
+                loader: 'ts-loader',
+                options: {
+                    transpileOnly: true
+                }
+            }]
+        },
+        {
+            test: /\.scss|css$/,
+            use: [{
+                loader: "style-loader"
             },
             {
-                test: /\.scss|css$/,
-                use: [{
-                        loader: "style-loader"
-                    },
-                    {
-                        loader: "css-loader"
-                    },
-                    {
-                        loader: "sass-loader"
-                    }
-                ]
+                loader: "css-loader"
             },
             {
-                test: /\.(jpg|png|pdf)$/,
-                use: [{
-                    loader: 'file-loader'
-                }]
-            },
-            {
-                test: /\.(png|jpg|gif)$/i,
-                use: [{
-                    loader: 'url-loader',
-                    options: {
-                        limit: 8192
-                    }
-                }]
+                loader: "sass-loader"
             }
+            ]
+        },
+        {
+            test: /\.(jpg|png|pdf)$/,
+            use: [{
+                loader: 'file-loader'
+            }]
+        },
+        {
+            test: /\.(png|jpg|gif)$/i,
+            use: [{
+                loader: 'url-loader',
+                options: {
+                    limit: 8192
+                }
+            }]
+        }
         ]
     },
     plugins,
-- 
cgit v1.2.3-70-g09d2


From 997e4ef9d7f79dd638cbcf6f2152f7b983fe646b Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 6 Aug 2020 09:55:08 -0700
Subject: fixed everything before merge (not cleaned)

---
 src/Utils.ts                        |   9 +++
 src/client/views/nodes/AudioBox.tsx | 133 ++++++++++++++++++------------------
 2 files changed, 75 insertions(+), 67 deletions(-)

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

diff --git a/src/Utils.ts b/src/Utils.ts
index a01a94134..3f82aa3eb 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -378,6 +378,15 @@ export function timenow() {
     return now.toLocaleDateString() + ' ' + h + ':' + m + ' ' + ampm;
 }
 
+export function formatTime(time: number) {
+    time = Math.round(time);
+    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');
+}
+
 export function aggregateBounds(boundsList: { x: number, y: number, width?: number, height?: number }[], xpad: number, ypad: number) {
     const bounds = boundsList.map(b => ({ x: b.x, y: b.y, r: b.x + (b.width || 0), b: b.y + (b.height || 0) })).reduce((bounds, b) => ({
         x: Math.min(b.x, bounds.x), y: Math.min(b.y, bounds.y),
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 682aaaeed..1d060120e 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -4,14 +4,14 @@ import { observer } from "mobx-react";
 import "./AudioBox.scss";
 import { Cast, DateCast, NumCast, FieldValue, ScriptCast } from "../../../fields/Types";
 import { AudioField, nullAudio } from "../../../fields/URLField";
-import { ViewBoxBaseComponent, ViewBoxAnnotatableComponent } from "../DocComponent";
+import { ViewBoxAnnotatableComponent } from "../DocComponent";
 import { makeInterface, createSchema } from "../../../fields/Schema";
 import { documentSchema } from "../../../fields/documentSchemas";
-import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero } from "../../../Utils";
+import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero, formatTime } from "../../../Utils";
 import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace, toJS } from "mobx";
 import { DateField } from "../../../fields/DateField";
 import { SelectionManager } from "../../util/SelectionManager";
-import { Doc, DocListCast } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { ContextMenu } from "../ContextMenu";
 import { Id } from "../../../fields/FieldSymbols";
@@ -21,22 +21,11 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { ComputedField, ScriptField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
-import { FormattedTextBox } from "./formattedText/FormattedTextBox";
-import { RichTextField } from "../../../fields/RichTextField";
-import { AudioResizer } from "./AudioResizer";
 import { List } from "../../../fields/List";
-import { LabelBox } from "./LabelBox";
-import { Transform } from "../../util/Transform";
 import { Scripting } from "../../util/Scripting";
-import { ColorBox } from "./ColorBox";
 import Waveform from "react-audio-waveform"
 import axios from "axios"
-
-// testing testing 
-
-interface Window {
-    MediaRecorder: MediaRecorder;
-}
+const _global = (window /* browser */ || global /* node */) as any;
 
 declare class MediaRecorder {
     // whatever MediaRecorder has
@@ -74,19 +63,18 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     _amount: number = 1;
     _markers: Array<any> = [];
     _first: boolean = false;
-    _buckets: Array<number> = new Array<number>();
+    _dragging = false;
+
     _count: Array<any> = [];
+    _timeline: Opt<HTMLDivElement>;
+    _duration = 0;
 
     private _isPointerDown = false;
     private _currMarker: any;
 
+    @observable _position: number = 0;
+    @observable _buckets: Array<number> = new Array<number>();
     @observable private _height: number = NumCast(this.layoutDoc.height);
-    @observable private _finish: boolean = false;
-    @observable private _dragging: boolean = false;
-    @observable private _duration = 0;
-    @observable private _rect: Array<any> = [];
-    // @observable private _buckets: Array<number> = new Array();
-
     @observable private _paused: boolean = false;
     @observable private static _scrubTime = 0;
     @observable private _repeat: boolean = false;
@@ -97,9 +85,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); }
     async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); }
 
-
     constructor(props: Readonly<FieldViewProps>) {
         super(props);
+
+        // onClick play script
         if (!AudioBox.RangeScript) {
             AudioBox.RangeScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!;
         }
@@ -107,8 +96,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         if (!AudioBox.LabelScript) {
             AudioBox.LabelScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!;
         }
-
-
     }
 
     componentWillUnmount() {
@@ -132,11 +119,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                     Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false);
                 }
             }, { fireImmediately: true });
+
+        // for play when link is selected
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
                 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) => {
                         let la1 = l.anchor1 as Doc;
                         let la2 = l.anchor2 as Doc;
@@ -163,13 +153,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             endTime = NumCast(la2.audioEnd);
                         }
 
-                        console.log(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);
                         }
                     });
                 }
+
+                // for links created during recording 
                 if (!link) {
                     this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime());
                     this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause();
@@ -178,6 +169,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime));
     }
 
+    // for updating the timecode
     timecodeChanged = () => {
         const htmlEle = this._ele;
         if (this.audioState !== "recording" && htmlEle) {
@@ -264,15 +256,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         runInAction(() => this.audioState = "recording");
         setTimeout(this.updateRecordTime, 0);
         this._recorder.start();
-        setTimeout(() => this._recorder && this.stopRecording(), 60 * 1000); // stop after an hour
+        setTimeout(() => this._recorder && this.stopRecording(), 60 * 60 * 1000); // stop after an hour
     }
 
     specificContextMenu = (e: React.MouseEvent): void => {
         const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" });
+        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" });
         funcs.push({ description: (this.layoutDoc.hideMarkers ? "Don't hide" : "Hide") + " markers", event: () => this.layoutDoc.hideMarkers = !this.layoutDoc.hideMarkers, icon: "expand-arrows-alt" });
         funcs.push({ description: (this.layoutDoc.hideLabels ? "Don't hide" : "Hide") + " labels", event: () => this.layoutDoc.hideLabels = !this.layoutDoc.hideLabels, icon: "expand-arrows-alt" });
-        funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" });
+        funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " markers onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" });
         ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
     }
 
@@ -364,10 +356,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         const buckets: number[] = [];
 
         axios({ url: this.path, responseType: "arraybuffer" })
-            .then(async response => {
+            .then(response => {
                 let audioData = response.data;
 
-                await audioCtx.decodeAudioData(audioData, buffer => {
+                audioCtx.decodeAudioData(audioData, action(buffer => {
                     let decodedAudioData = buffer.getChannelData(0);
                     const NUMBER_OF_BUCKETS = 100;
                     let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
@@ -386,7 +378,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                         this._buckets.push(size / 2);
                     }
 
-                });
+                }));
                 return buckets;
             });
     }
@@ -489,8 +481,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         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: "", isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, 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)})`)
         } else {
@@ -508,8 +500,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         this._isPointerDown = true;
         console.log("click");
         this._currMarker = m;
-        const targetele = document.getElementById("timeline");
-        targetele?.setPointerCapture(e.pointerId);
+        this._timeline?.setPointerCapture(e.pointerId);
         this._left = left;
 
 
@@ -529,8 +520,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         const rect = (e.target as any).getBoundingClientRect();
         this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
-        const targetele = document.getElementById("timeline");
-        targetele?.releasePointerCapture(e.pointerId);
+        this._timeline?.releasePointerCapture(e.pointerId);
 
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
@@ -640,13 +630,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         return max - 1
     }
 
-    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');
-    }
 
     @action
     onHover = () => {
@@ -719,21 +702,32 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     @computed get waveform() {
         return <Waveform
-            color={"blue"}
+            color={"darkblue"}
             height={this._height}
             barWidth={0.1}
-            pos={this.layoutDoc.currentTimecode}
+            // pos={this.layoutDoc.currentTimecode}
+            pos={this.dataDoc.duration}
             duration={this.dataDoc.duration}
             peaks={this._buckets.length === 100 ? this._buckets : undefined}
             progressColor={"blue"} />;
     }
 
+    timelineRef = (timeline: HTMLDivElement) => {
+        const observer = new _global.ResizeObserver(action((entries: any) => {
+            for (const entry of entries) {
+                this.update(entry.contentRect.width, entry.contentRect.height);
+                this._position = entry.contentRect.width;
+            }
+        }));
+        timeline && observer.observe(timeline);
+
+        this._timeline = timeline;
+    }
+
     @action
-    update = () => {
-        if (this.layoutDoc._height) {
+    update = (width: number, height: number) => {
+        if (height) {
             this._height = 0.8 * NumCast(this.layoutDoc._height);
-            console.log(document.getElementById("timeline")?.clientWidth);
-            let width = document.getElementById("timeline")?.clientWidth;
             let canvas2 = document.getElementsByTagName("canvas")[0];
             if (canvas2) {
                 let oldWidth = canvas2.width;
@@ -747,6 +741,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (context) {
                     context.scale(ratio1, ratio2)
                 }
+
+
             }
 
             let canvas1 = document.getElementsByTagName("canvas")[1];
@@ -761,19 +757,24 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 let context = canvas1.getContext('2d');
                 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}`;
+                // }
             }
         }
     }
 
 
     render() {
-        //trace();
+        trace();
         const interactive = this.active() ? "-interactive" : "";
         this.reset();
-        this.update();
         // this.waveform();
+        this.path && this._buckets.length !== 100 ? this.buckets() : null;
         return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
             {!this.path ?
                 <div className="audiobox-buttons">
@@ -795,7 +796,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             <div className="buttons" onClick={this._paused ? this.recordPlay : this.recordPause}>
                                 <FontAwesomeIcon style={{ width: "100%" }} icon={this._paused ? "play" : "pause"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} />
                             </div>
-                            <div className="time">{this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}</div>
+                            <div className="time">{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}</div>
                         </div>
 
                         :
@@ -803,13 +804,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                             RECORD
                             </button>}
                 </div> :
-                <div className="audiobox-controls" onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}>
+                <div className="audiobox-controls" > {/*onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}*/}
                     <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" id="timeline" onClick={e => { e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change}
+                        <div className="audiobox-timeline" ref={this.timelineRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change}
                             onPointerDown={e => {
                                 e.stopPropagation();
                                 e.preventDefault();
@@ -823,8 +824,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                     }
                                 }
                                 if (e.button === 0 && e.altKey) {
-
-                                    this.newMarker(Docs.Create.LabelDocument({ title: "", useLinkSmallAnchor: true, hideLinkButton: true, isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
+                                    this.newMarker(Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart)`) as any, useLinkSmallAnchor: true, hideLinkButton: true, isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
                                 }
 
                                 if (e.button === 0 && e.shiftKey) {
@@ -834,7 +834,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 }
                             }}>
                             <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
-                                {console.log(this.peaks)}
+                                {/* {console.log(this.peaks)} */}
                                 {/* <Waveform
                                     color={"#000000"}
                                     height={this._height}
@@ -853,7 +853,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 + 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={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 className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
                                             <DocumentView {...this.props}
                                                 Document={m}
@@ -928,18 +928,18 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                             LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
                                         />
                                         <div key={i} className={`audiobox-marker`} onPointerEnter={() => Doc.linkFollowHighlight(la1)}
-                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
+                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
                                     </div>;
                             })}
-                            <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
+                            <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">
-                            {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+                            {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
                         </div>
                         <div className="total-time">
-                            {this.formatTime(Math.round(NumCast(this.dataDoc.duration)))}
+                            {formatTime(Math.round(NumCast(this.dataDoc.duration)))}
                         </div>
                     </div>
                 </div>
@@ -947,5 +947,4 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         </div>;
     }
 }
-
-// Scripting.addGlobal(function playFrom(audioDoc: Doc, start: number, end: number) { return audioDoc.playFrom(start, end); })
\ No newline at end of file
+Scripting.addGlobal(function formatToTime(time: number): any { return formatTime(time); });
\ No newline at end of file
-- 
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/AudioBox.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 72b95c76f156a15f645703ba77c05aeb62c903ff Mon Sep 17 00:00:00 2001
From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com>
Date: Thu, 6 Aug 2020 17:34:09 -0700
Subject: minor fixes

---
 src/client/documents/Documents.ts   |  1 -
 src/client/views/nodes/AudioBox.tsx | 10 ++++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 402f3e82c..aa74ef71a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -564,7 +564,6 @@ export namespace Docs {
 
             viewDoc.author = Doc.CurrentUserEmail;
             viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc);
-            console.log("audio link!");
 
             return Doc.assign(viewDoc, delegateProps, true);
         }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 11dfe5fe6..f01382d43 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -191,7 +191,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
     // pause play back
     pause = action(() => {
-        console.log("pause");
         this._ele!.pause();
         this.audioState = "paused";
     });
@@ -215,7 +214,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                     this.pause();
                 }
             } else if (seekTimeInSeconds <= this._ele.duration) {
-                console.log("playing");
                 this._ele.currentTime = seekTimeInSeconds;
                 this._ele.play();
                 runInAction(() => this.audioState = "playing");
@@ -425,7 +423,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     onPointerMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        console.log("drag");
 
         if (!this._isPointerDown) {
             return;
@@ -592,6 +589,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                 if (context) {
                     context.scale(ratio1, ratio2)
                 }
+
+                let parent = canvas1.parentElement;
+                if (parent) {
+                    parent.style.width = `${width}`;
+                    parent.style.height = `${this._height}`;
+                }
             }
         }
     }
@@ -604,7 +607,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     reset = () => this._first = true;
 
     render() {
-        trace();
         const interactive = this.active() ? "-interactive" : "";
         this.reset();
         this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording
-- 
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/AudioBox.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

