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 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/client/views/nodes/AudioBox.scss') 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; -- cgit v1.2.3-70-g09d2 From 2961955e2e6ee993252435f0e1358b305c0817b3 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Tue, 7 Jul 2020 14:09:07 -0700 Subject: pause and time --- src/client/views/nodes/AudioBox.scss | 33 ++++++++++++++++--- src/client/views/nodes/AudioBox.tsx | 61 +++++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 13 deletions(-) (limited to 'src/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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 502981833ef7f9e8179bf9c487b1e35404c6d4e1 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Tue, 28 Jul 2020 15:08:56 -0700 Subject: fix recursion bug and make link turn blue --- src/client/views/nodes/AudioBox.scss | 2 +- src/client/views/nodes/AudioBox.tsx | 34 ++++++++++++++++++---- .../views/nodes/formattedText/FormattedTextBox.tsx | 24 +++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/AudioBox.scss') 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 58f75d38dcfd113c90e4e27e55468d06412c653e Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 1 Aug 2020 16:34:48 -0700 Subject: fixed bugs and added waveform (need fix) --- package-lock.json | 36 ++++++++++++++ package.json | 2 + src/client/documents/Documents.ts | 2 +- src/client/views/nodes/AudioBox.scss | 10 +++- src/client/views/nodes/AudioBox.tsx | 91 +++++++++++++++++++++++++++++++++++- src/typings/index.d.ts | 1 + 6 files changed, 139 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes/AudioBox.scss') 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/client/views/nodes/AudioBox.scss') 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