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.scss | 14 ++++++++++++++ src/client/views/nodes/AudioBox.tsx | 31 ++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index c959b79f5..2655f2377 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -45,6 +45,15 @@ width: 100%; height: 100%; position: relative; + + .recording { + width: 100%; + height: 100%; + position: relative; + display: flex; + padding-left: 2px; + background: lightgrey; + } } .audiobox-controls { @@ -53,6 +62,7 @@ position: relative; display: flex; padding-left: 2px; + background: lightgrey; .audiobox-player { margin-top: auto; @@ -72,6 +82,10 @@ padding: 2px; } + .audiobox-playhead:hover { + background-color: darkgrey; + } + .audiobox-dictation { align-items: center; display: inherit; 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 { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @@ -106,8 +107,12 @@ export class AudioBox extends ViewBoxBaseComponent { - 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; } + @action + onRepeat = (e: React.MouseEvent) => { + this._repeat = !this._repeat; + e.stopPropagation(); + } + render() { const interactive = this.active() ? "-interactive" : ""; return
@@ -231,13 +242,19 @@ export class AudioBox extends ViewBoxBaseComponent
: -
-
-
-
+
+
+
+
+
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') 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 { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @@ -81,7 +80,7 @@ export class AudioBox extends ViewBoxBaseComponent 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 { - 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 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 { + console.log("click"); this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1); e.stopPropagation(); } @@ -227,12 +224,6 @@ export class AudioBox extends ViewBoxBaseComponent; } - @action - onRepeat = (e: React.MouseEvent) => { - this._repeat = !this._repeat; - e.stopPropagation(); - } - render() { const interactive = this.active() ? "-interactive" : ""; return
@@ -242,19 +233,13 @@ export class AudioBox extends ViewBoxBaseComponent
: -
-
-
-
-
+
+
+
+
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') 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 { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @@ -80,7 +81,7 @@ export class AudioBox extends ViewBoxBaseComponent 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 { - 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 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 { - console.log("click"); this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1); e.stopPropagation(); } @@ -224,6 +227,12 @@ export class AudioBox extends ViewBoxBaseComponent; } + @action + onRepeat = (e: React.MouseEvent) => { + this._repeat = !this._repeat; + e.stopPropagation(); + } + render() { const interactive = this.active() ? "-interactive" : ""; return
@@ -233,13 +242,19 @@ export class AudioBox extends ViewBoxBaseComponent
: -
-
-
-
+
+
+
+
+
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') 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 { 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 { 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 { + 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
@@ -241,14 +272,28 @@ export class AudioBox extends ViewBoxBaseComponent
- +
: "RECORD"} + */} + {this.audioState === "recording" ? +
e.stopPropagation()}> +
+ +
+
+ +
+
{NumCast(this.layoutDoc.currentTimecode).toFixed(1)}
+
+ + : + }
:
-- 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') 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 = [] + @observable private _markers: Array = []; @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @observable private _repeat: boolean = false; @@ -122,7 +130,12 @@ export class AudioBox extends ViewBoxBaseComponent { 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 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 @@ -304,12 +340,40 @@ export class AudioBox extends ViewBoxBaseComponent { 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 = +
{ this.playFrom(m[0], m[1]); e.stopPropagation() }}> + {/* */} +
+ : + rect = +
+ {/* */} +
; + 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 +
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') 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 = [] @observable private _markers: Array = []; @@ -300,6 +304,85 @@ export class AudioBox extends ViewBoxBaseComponent { + 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
@@ -357,13 +440,14 @@ export class AudioBox extends ViewBoxBaseComponent {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 = -
{ this.playFrom(m[0], m[1]); e.stopPropagation() }}> +
{ this.playFrom(m[0], m[1]); e.stopPropagation() }} > {/* */} +
this.onPointerDown(e, m)}>
: rect = @@ -372,7 +456,7 @@ export class AudioBox extends ViewBoxBaseComponent */}
; - 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 {this.audio}
+
+ {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} +
+
+ {this.formatTime(Math.round(NumCast(this.layoutDoc.duration)))} +
} 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
+ } +} \ 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') 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 = [] @observable private _markers: Array = []; @@ -288,6 +291,7 @@ export class AudioBox extends ViewBoxBaseComponent { + 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 { 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 { 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 { + 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
{!this.path ? @@ -406,7 +434,7 @@ export class AudioBox extends ViewBoxBaseComponent
-
{NumCast(this.layoutDoc.currentTimecode).toFixed(1)}
+
{this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
: @@ -415,19 +443,24 @@ export class AudioBox extends ViewBoxBaseComponent}
:
+
+
-
-
-
-
e.stopPropagation()} +
+ {/*
+
*/} +
{ 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 { // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false }); let rect; + console.log(1 / this._amount * 100); (m.length > 1) ? rect = -
{ this.playFrom(m[0], m[1]); e.stopPropagation() }} > - {/* */} -
this.onPointerDown(e, m)}>
+
{ this.playFrom(m[0], m[1]); e.stopPropagation() }} > + {/* */} +
this.onPointerDown(e, m, true)}>
+
this.onPointerDown(e, m, false)}>
: rect = @@ -470,7 +505,7 @@ export class AudioBox extends ViewBoxBaseComponent +
{ if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); wasPaused && this.pause(); e.stopPropagation(); } }} />
; })} -
+
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> {this.audio} +
{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') 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(AudioDocument) { +export class AudioBox extends ViewBoxAnnotatableComponent(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 = [] + @observable private _rect: Array = []; @observable private _markers: Array = []; @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @@ -86,6 +92,9 @@ export class AudioBox extends ViewBoxBaseComponent this.audioState = this.path ? "paused" : undefined); this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID, scrollLinkId => { @@ -289,8 +298,15 @@ export class AudioBox extends ViewBoxBaseComponent(this._markers) + } + + console.log(this.dataDoc.markers) this._amount++; } @@ -304,7 +320,13 @@ export class AudioBox extends ViewBoxBaseComponent([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 { - 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 - {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 = -
{ this.playFrom(m[0], m[1]); e.stopPropagation() }} > +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > {/* */}
this.onPointerDown(e, m, true)}>
+ ScriptCast(ScriptField.MakeScript("this.playFrom((NumCast(m.audioStart), NumCast(m.audioEnd)))"))} + ignoreAutoHeight={false} + ScreenToLocalTransform={Transform.Identity} + bringToFront={emptyFunction} + backgroundColor={returnTransparent} /> + {/* */}
this.onPointerDown(e, m, false)}>
: rect = -
+
{/* */} @@ -539,4 +606,6 @@ export class AudioBox extends ViewBoxBaseComponent; } -} \ 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') 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) { + 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 this.audioState = this.path ? "paused" : undefined); this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID, scrollLinkId => { @@ -299,15 +309,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent(this._markers) + this.dataDoc[this.annotationKey] = new List([marker]); } - - console.log(this.dataDoc.markers) - this._amount++; } start(marker: number) { @@ -322,9 +328,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent([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([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 { - 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 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 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} /> {/* */} + {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/}
this.onPointerDown(e, m, false)}>
: rect =
- {/* */} +
; return rect; })} @@ -572,23 +592,23 @@ export class AudioBox extends ViewBoxAnnotatableComponent -
- -
+
e.stopPropagation()}> + {/*
*/} + + {/*
*/}
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(); } }} />
; })}
{ 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(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') 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 = []; private _isPointerDown = false; private _currMarker: any; @@ -76,7 +79,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; - @observable private _markers: Array = []; + @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @observable private _repeat: boolean = false; @@ -90,9 +93,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent) { 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 -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([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([newMarker]); } + this._start = 0; this._amount++; } @@ -407,21 +420,21 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + 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 { + // 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 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 { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > - {/* */}
this.onPointerDown(e, m, true)}>
{/* */} {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/} @@ -574,13 +609,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent + bringToFront={emptyFunction} + scriptContext={this} />
; 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 {/*
*/}
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(); } }} />
; })} -
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> +
{ e.stopPropagation(); e.preventDefault(); console.log("hi"); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> {this.audio}
-- 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') 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 -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 { 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 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
{!this.path ? @@ -568,56 +572,56 @@ export class AudioBox extends ViewBoxAnnotatableComponent {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 = -
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > -
this.onPointerDown(e, m, true)}>
- - {/* */} - {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/} -
this.onPointerDown(e, m, false)}>
-
+ (this.layoutDoc.hideMarkers) ? (null) : + rect = +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > +
this.onPointerDown(e, m, true)}>
+ + {/* */} + {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/} +
this.onPointerDown(e, m, false)}>
+
: - rect = -
- -
; + (this.layoutDoc.hideLabels) ? (null) : + rect = +
+ +
; 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 e.stopPropagation()}> @@ -648,7 +660,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
; })} -
{ e.stopPropagation(); e.preventDefault(); console.log("hi"); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> {this.audio}
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 = (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') 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 = []; + _first: boolean = false; private _isPointerDown = false; private _currMarker: any; @@ -128,6 +129,22 @@ export class AudioBox extends ViewBoxAnnotatableComponent 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 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 { 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 { 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 { + this._first = true; + } + render() { //trace(); const interactive = this.active() ? "-interactive" : ""; + this.reset(); return
{!this.path ?
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 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') 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 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 e.stopPropagation()}> {/*
*/} @@ -672,15 +665,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent - {/*
*/} -
Doc.linkFollowHighlight(la1)} + backgroundColor={returnTransparent} + ContentScaling={returnOne} + forcedBackgroundColor={returnTransparent} + pointerEvents={false} + LayoutTemplate={undefined} + LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)} + /> +
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(); } }} />
; })} 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(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) => -- 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') 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 = []; _first: boolean = false; + _buckets: Array = new Array(); private _isPointerDown = false; private _currMarker: any; @@ -80,6 +82,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; + // @observable private _buckets: Array = new Array(); @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @@ -299,6 +302,81 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + 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
:
-
-
+
-
+
{/*
*/}
{ e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change} @@ -711,6 +762,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{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') 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 = []; @@ -686,14 +688,92 @@ export class AudioBox extends ViewBoxAnnotatableComponent; + } + + @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
{!this.path ?
@@ -755,15 +835,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{console.log(this.peaks)} - + progressColor={"#0000ff"} /> */} + {this.waveform} + {/* {this.waveform} */}
{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') 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 = []; _first: boolean = false; - _buckets: Array = new Array(); + _dragging = false; + _count: Array = []; + _timeline: Opt; + _duration = 0; private _isPointerDown = false; private _currMarker: any; + @observable _position: number = 0; + @observable _buckets: Array = new Array(); @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 = []; - // @observable private _buckets: Array = 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) { 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 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 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 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 { + .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 { - 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; } + 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 {!this.path ?
@@ -795,7 +796,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
-
{this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
: @@ -803,13 +804,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent}
: -
+
{/*onClick={this.layoutDoc.playOnSelect ? this.onPlay : undefined}*/}
{/*
*/} -
{ e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change} +
{ e.stopPropagation(); e.preventDefault(); }} onDoubleClick={e => this.change} onPointerDown={e => { e.stopPropagation(); e.preventDefault(); @@ -823,8 +824,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
- {console.log(this.peaks)} + {/* {console.log(this.peaks)} */} {/* { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} >
this.onPointerDown(e, m, true)}>
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(); } }} />
; })} -
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} /> {this.audio}
- {this.formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} + {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
- {this.formatTime(Math.round(NumCast(this.dataDoc.duration)))} + {formatTime(Math.round(NumCast(this.dataDoc.duration)))}
@@ -947,5 +947,4 @@ export class AudioBox extends ViewBoxAnnotatableComponent; } } - -// 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') 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 = []; _first: boolean = false; _dragging = false; @@ -77,7 +76,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @@ -126,36 +124,38 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + // 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 { - 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 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 { this._stream = await navigator.mediaDevices.getUserMedia({ audio: true }); this._recorder = new MediaRecorder(this._stream); @@ -259,6 +260,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent 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 { this._recorder.stop(); this._recorder = undefined; @@ -278,6 +281,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { this._recorder ? this.stopRecording() : this.recordAudioAnnotation(); @@ -285,14 +289,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent { 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 { 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