From da61cf1a3b9b37d43087b16be75af162cfb8b5cf Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 15:52:16 -0700 Subject: working version of click and drag --- src/client/views/nodes/AudioBox.tsx | 102 ++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 10 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index f01382d43..db87b15d1 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -60,20 +60,26 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _first: boolean = false; _dragging = false; _count: Array = []; _timeline: Opt; _duration = 0; + @observable _visible: boolean = false; + _containerX: number = 0; + _containerY: number = 0; + @observable _currX: number = 0; + @observable _currY: number = 0; + _invertedX: boolean = false; + _invertedY: boolean = false; private _isPointerDown = false; private _currMarker: any; @observable _position: number = 0; @observable _buckets: Array = new Array(); - @observable private _height: number = NumCast(this.layoutDoc.height); + @observable _waveHeight = this.layoutDoc._height; @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @computed get audioState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.audioState as (undefined | "recording" | "paused" | "playing"); } @@ -355,6 +361,74 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + e.stopPropagation(); + e.preventDefault(); + this._isPointerDown = true; + this._timeline?.setPointerCapture(e.pointerId); + + this.start(this._ele!.currentTime); + + const rect = (e.target as any).getBoundingClientRect(); + this._containerX = this._currX = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); + this._containerY = this._currY = (e.clientY - rect.y) / rect.height; + console.log(rect.height); + + document.removeEventListener("pointermove", this.onPointerMoveTimeline); + document.addEventListener("pointermove", this.onPointerMoveTimeline); + document.removeEventListener("pointerup", this.onPointerUpTimeline); + document.addEventListener("pointerup", this.onPointerUpTimeline); + + } + + // ending the drag event for marker resizing + @action + onPointerUpTimeline = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + this._isPointerDown = false; + + const rect = (e.target as any).getBoundingClientRect(); + const time = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration) + this._visible ? this.end(time) : this._start = 0; + this._visible = false; + + this._containerX = 0; + this._containerY = 0; + this._timeline?.releasePointerCapture(e.pointerId); + + document.removeEventListener("pointermove", this.onPointerMoveTimeline); + document.removeEventListener("pointerup", this.onPointerUpTimeline); + } + + // resizes the marker while dragging + @action + onPointerMoveTimeline = (e: PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + + if (!this._isPointerDown) { + return; + } + this._visible = true; + const rect = (e.target as any).getBoundingClientRect(); + console.log(rect.height); + + this._currX = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); + this._currY = (e.clientY - rect.y) / rect.height; + + (this._currX - this._containerX < 0) ? this._invertedX = true : this._invertedX = false; + + this._currY - this._containerY < 0 ? this._invertedY = true : this._invertedY = false; + console.log(this._invertedY); + } + + @computed get container() { + return
+ } + // creates a new label @action newMarker(marker: Doc) { @@ -376,7 +450,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (height) { - this._height = 0.8 * NumCast(this.layoutDoc._height); + const height = 0.8 * NumCast(this.layoutDoc._height); let canvas2 = document.getElementsByTagName("canvas")[0]; if (canvas2) { let oldWidth = canvas2.width; let oldHeight = canvas2.height; - canvas2.style.height = `${this._height}`; + canvas2.style.height = `${height}`; canvas2.style.width = `${width}`; let ratio1 = oldWidth / window.innerWidth; @@ -580,7 +657,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent -
+
{this.waveform}
{DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => { @@ -666,7 +746,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { 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)}>
{ if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
; })} + {this._visible ? this.container : null} +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} /> {this.audio}
-- cgit v1.2.3-70-g09d2 From e8907b549dce6c991de92c9e8038e08c76725b18 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:16:14 -0700 Subject: changed to 100% height and added minimum width dragged --- src/client/views/nodes/AudioBox.tsx | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index db87b15d1..9d3d157c3 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -7,7 +7,7 @@ import { AudioField, nullAudio } from "../../../fields/URLField"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { makeInterface, createSchema } from "../../../fields/Schema"; import { documentSchema } from "../../../fields/documentSchemas"; -import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero, formatTime } from "../../../Utils"; +import { Utils, returnTrue, emptyFunction, returnOne, returnTransparent, returnFalse, returnZero, formatTime, setupMoveUpEvents } from "../../../Utils"; import { runInAction, observable, reaction, IReactionDisposer, computed, action, trace, toJS } from "mobx"; import { DateField } from "../../../fields/DateField"; import { SelectionManager } from "../../util/SelectionManager"; @@ -25,6 +25,7 @@ import { List } from "../../../fields/List"; import { Scripting } from "../../util/Scripting"; import Waveform from "react-audio-waveform" import axios from "axios" +import { DragManager } from "../../util/DragManager"; const _global = (window /* browser */ || global /* node */) as any; declare class MediaRecorder { @@ -66,17 +67,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _timeline: Opt; _duration = 0; - @observable _visible: boolean = false; _containerX: number = 0; - _containerY: number = 0; - @observable _currX: number = 0; - @observable _currY: number = 0; _invertedX: boolean = false; - _invertedY: boolean = false; - private _isPointerDown = false; private _currMarker: any; + @observable _visible: boolean = false; + @observable _currX: number = 0; @observable _position: number = 0; @observable _buckets: Array = new Array(); @observable _waveHeight = this.layoutDoc._height; @@ -373,14 +370,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent 15) ? this.end(time) : this._start = 0; this._visible = false; this._containerX = 0; - this._containerY = 0; this._timeline?.releasePointerCapture(e.pointerId); document.removeEventListener("pointermove", this.onPointerMoveTimeline); @@ -414,19 +409,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent
+ return
} // creates a new label -- cgit v1.2.3-70-g09d2 From 1032f8b421402371be4e4d62171bc837fdcb4368 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 17:31:54 -0700 Subject: changed from alt to shift key --- src/client/views/nodes/AudioBox.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 9d3d157c3..9347e9b5b 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -719,15 +719,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{this.waveform} -- cgit v1.2.3-70-g09d2 From 25fa93e7060c8f8561c294c7309c763e3b8f9313 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 8 Aug 2020 18:23:50 -0700 Subject: minor fixes --- src/client/views/nodes/AudioBox.tsx | 4 ++-- src/server/index.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 59b60defa..4805b8643 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -739,8 +739,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} >
this.onPointerDown(e, m, true)}>
diff --git a/src/server/index.ts b/src/server/index.ts index 9185e3c5e..4ac4de847 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -105,7 +105,6 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: const serve: PublicHandler = ({ req, res }) => { const detector = new mobileDetect(req.headers['user-agent'] || ""); const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html'; - console.log(detector.is("iPhone")); res.sendFile(path.join(__dirname, '../../deploy/' + filename)); }; -- cgit v1.2.3-70-g09d2 From ce3e3b1b217a02a65a3bc4eae5eccb7ca0842fac Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 10:57:25 -0400 Subject: cleaning up AudioBox --- src/Utils.ts | 4 +- src/client/views/nodes/AudioBox.scss | 3 +- src/client/views/nodes/AudioBox.tsx | 357 +++++++++++------------------------ 3 files changed, 117 insertions(+), 247 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index 0be27b25d..d9a5353e8 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -547,7 +547,7 @@ export function setupMoveUpEvents( target: object, e: React.PointerEvent, moveEvent: (e: PointerEvent, down: number[], delta: number[]) => boolean, - upEvent: (e: PointerEvent) => void, + upEvent: (e: PointerEvent, movement: number[]) => void, clickEvent: (e: PointerEvent, doubleTap?: boolean) => void, stopPropagation: boolean = true, stopMovePropagation: boolean = true @@ -571,7 +571,7 @@ export function setupMoveUpEvents( const _upEvent = (e: PointerEvent): void => { (target as any)._doubleTap = (Date.now() - (target as any)._lastTap < 300); (target as any)._lastTap = Date.now(); - upEvent(e); + upEvent(e, [e.clientX - (target as any)._downX, e.clientY - (target as any)._downY]); if (Math.abs(e.clientX - (target as any)._downX) < 4 && Math.abs(e.clientY - (target as any)._downY) < 4) { clickEvent(e, (target as any)._doubleTap); } diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index c0743933e..973de979e 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -179,7 +179,8 @@ height: 100%; overflow: hidden; z-index: -1000; - bottom: -30%; + bottom: 0; + pointer-events: none; } .audiobox-linker, diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 4805b8643..0fb191c05 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -31,9 +31,7 @@ declare class MediaRecorder { // whatever MediaRecorder has constructor(e: any); } -export const audioSchema = createSchema({ - playOnSelect: "boolean" -}); +export const audioSchema = createSchema({ playOnSelect: "boolean" }); type AudioDocument = makeInterface<[typeof documentSchema, typeof audioSchema]>; const AudioDocument = makeInterface(documentSchema, audioSchema); @@ -66,13 +64,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _timeline: Opt; _duration = 0; - _containerX: number = 0; - _invertedX: boolean = false; - private _isPointerDown = false; + _markerStart: number = 0; private _currMarker: any; @observable _visible: boolean = false; - @observable _currX: number = 0; + @observable _markerEnd: number = 0; @observable _position: number = 0; @observable _buckets: Array = new Array(); @observable _waveHeight: number | undefined = this.layoutDoc._height; @@ -82,6 +78,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); } + @computed get audioDuration() { return NumCast(this.dataDoc.duration); } async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); } constructor(props: Readonly) { @@ -137,21 +134,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + playFrom = (seekTimeInSeconds: number, endTime: number = this.audioDuration) => { let play; clearTimeout(play); this._duration = endTime - seekTimeInSeconds; @@ -218,7 +205,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.audioState = "playing"); - if (endTime !== this.dataDoc.duration) { + if (endTime !== this.audioDuration) { play = setTimeout(() => this.pause(), (this._duration) * 1000); // use setTimeout to play a specific duration } } else { @@ -230,11 +217,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (this.audioState === "recording") { + setTimeout(this.updateRecordTime, 30); 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; } } @@ -353,74 +339,55 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - e.stopPropagation(); - e.preventDefault(); - this._isPointerDown = true; - this._timeline?.setPointerCapture(e.pointerId); - - this.start(this._ele!.currentTime); - const rect = (e.target as any).getBoundingClientRect(); - this._containerX = this._currX = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); - - document.removeEventListener("pointermove", this.onPointerMoveTimeline); - document.addEventListener("pointermove", this.onPointerMoveTimeline); - document.removeEventListener("pointerup", this.onPointerUpTimeline); - document.addEventListener("pointerup", this.onPointerUpTimeline); + const toTimeline = (screen_delta: number) => screen_delta / rect.width * this.audioDuration; + this._markerStart = this._markerEnd = toTimeline(e.clientX - rect.x); + setupMoveUpEvents(this, e, action((e: PointerEvent) => { + this._visible = true; + this._markerEnd = toTimeline(e.clientX - rect.x); + if (this._markerEnd < this._markerStart) { + const tmp = this._markerStart; + this._markerStart = this._markerEnd; + this._markerEnd = tmp; + } + return false; + }), + action((e: PointerEvent, movement: number[]) => { + if (Math.abs(movement[0]) > 15) { + this.createNewMarker(this._markerStart, toTimeline(e.clientX - rect.x)); + } + this._visible = false; + }), + emptyFunction); } - - // ending the drag event for marker resizing - @action - onPointerUpTimeline = (e: PointerEvent): void => { - e.stopPropagation(); - e.preventDefault(); - this._isPointerDown = false; - - const rect = (e.target as any).getBoundingClientRect(); - const time = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); - - // if drag is greater than 15px (didn't use setupMoveEvent) - (this._visible && Math.abs(this._currX - this._containerX) * rect.width / NumCast(this.dataDoc.duration) > 15) ? this.end(time) : this._start = 0; - this._visible = false; - - this._containerX = 0; - this._timeline?.releasePointerCapture(e.pointerId); - - document.removeEventListener("pointermove", this.onPointerMoveTimeline); - document.removeEventListener("pointerup", this.onPointerUpTimeline); + // returns the selection container + @computed get container() { + return
} - // resizes the marker while dragging + // creates a new marker @action - onPointerMoveTimeline = (e: PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - - if (!this._isPointerDown) { - return; - } - this._visible = true; - const rect = (e.target as any).getBoundingClientRect(); - - this._currX = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); - - (this._currX - this._containerX < 0) ? this._invertedX = true : this._invertedX = false; + createNewMarker(audioStart: number, audioEnd: number) { + const newMarker = Docs.Create.LabelDocument({ + title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, + useLinkSmallAnchor: true, hideLinkButton: true, audioStart, audioEnd, _showSidebar: false, + _autoHeight: true, annotationOn: this.props.Document + }) + this.addMark(newMarker); } - // returns the selection container - @computed get container() { - return
- } - - // creates a new label + // adds an annotation marker or label @action - newMarker(marker: Doc) { + addMark(marker: Doc) { marker.data = ""; if (this.dataDoc[this.annotationKey]) { this.dataDoc[this.annotationKey].push(marker); @@ -429,104 +396,39 @@ export class AudioBox extends ViewBoxAnnotatableComponent([newMarker]); - } - - this._start = 0; - } - // starting the drag event for marker resizing onPointerDown = (e: React.PointerEvent, m: any, left: boolean): void => { - e.stopPropagation(); - e.preventDefault(); - this._isPointerDown = true; this._currMarker = m; - this._timeline?.setPointerCapture(e.pointerId); this._left = left; - - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - } - - // ending the drag event for marker resizing - @action - onPointerUp = (e: PointerEvent): void => { - e.stopPropagation(); - 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); - - this._timeline?.releasePointerCapture(e.pointerId); - - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - } - - // resizes the marker while dragging - onPointerMove = async (e: PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - - if (!this._isPointerDown) { - return; - } - - const rect = await (e.target as any).getBoundingClientRect(); - - const newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration); - - this.changeMarker(this._currMarker, newTime); + const toTimeline = (screen_delta: number) => screen_delta / rect.width * this.audioDuration; + setupMoveUpEvents(this, e, () => { + this.changeMarker(this._currMarker, toTimeline(e.clientX - rect.x)); + return false; + }, + () => this._ele!.currentTime = this.layoutDoc.currentTimecode = toTimeline(e.clientX - rect.x), + emptyFunction); } // updates the marker with the new time @action changeMarker = (m: any, time: any) => { - DocListCast(this.dataDoc[this.annotationKey]).forEach((marker: Doc) => { - if (this.isSame(marker, m)) { - this._left ? marker.audioStart = time : marker.audioEnd = time; - } - }); + DocListCast(this.dataDoc[this.annotationKey]).filter(marker => this.isSame(marker, m)).forEach(marker => + this._left ? marker.audioStart = time : marker.audioEnd = time); } // checks if the two markers are the same with start and end time isSame = (m1: any, m2: any) => { - if (m1.audioStart === m2.audioStart && m1.audioEnd === m2.audioEnd) { - return true; - } - return false; + return m1.audioStart === m2.audioStart && m1.audioEnd === m2.audioEnd; } // instantiates a new array of size 500 for marker layout markers = () => { - const increment = NumCast(this.layoutDoc.duration) / 500; + const increment = this.audioDuration / 500; this._count = []; for (let i = 0; i < 500; i++) { this._count.push([increment * i, 0]); } - } // makes sure no markers overlaps each other by setting the correct position and width @@ -551,7 +453,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent= m.audioStart && this._count[i][0] <= m.audioEnd) { this._count[i][1] = max; } - } if (this.dataDoc.markerAmount < max) { @@ -567,8 +468,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent; } @@ -612,10 +513,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent { 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; - } + Array.from(entries).map(e => e as any).filter(e => e.contentRect.width).forEach(e => { + this.update(e.contentRect.width, e.contentRect.height); + this._position = e.contentRect.width; + }) })); timeline && observer.observe(timeline); @@ -625,36 +526,29 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + const scaleCanvas = (canvas: HTMLCanvasElement) => { + let oldWidth = canvas.width; + let oldHeight = canvas.height; + canvas.style.height = `${height}`; + canvas.style.width = `${width}`; + + const ratio1 = oldWidth / window.innerWidth; + const ratio2 = oldHeight / window.innerHeight; + const context = canvas.getContext('2d'); + if (context) { + context.scale(ratio1, ratio2); + } + } if (height) { const height = 0.8 * NumCast(this.layoutDoc._height); let canvas2 = document.getElementsByTagName("canvas")[0]; if (canvas2) { - let oldWidth = canvas2.width; - let oldHeight = canvas2.height; - canvas2.style.height = `${height}`; - canvas2.style.width = `${width}`; - - const ratio1 = oldWidth / window.innerWidth; - const ratio2 = oldHeight / window.innerHeight; - const context = canvas2.getContext('2d'); - if (context) { - context.scale(ratio1, ratio2); - } + scaleCanvas(canvas2); } const canvas1 = document.getElementsByTagName("canvas")[1]; if (canvas1) { - const oldWidth = canvas1.width; - const oldHeight = canvas1.height; - canvas1.style.height = `${height}`; - canvas1.style.width = `${width}`; - - const ratio1 = oldWidth / window.innerWidth; - const ratio2 = oldHeight / window.innerHeight; - const context = canvas1.getContext('2d'); - if (context) { - context.scale(ratio1, ratio2); - } + scaleCanvas(canvas1); const parent = canvas1.parentElement; if (parent) { @@ -666,16 +560,28 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox.RangeScript; - labelScript = () => AudioBox.LabelScript; - // for indicating the first marker that is rendered - reset = () => this._first = true; - render() { const interactive = this.active() ? "-interactive" : ""; - this.reset(); + this._first = true; // for indicating the first marker that is rendered this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording + const markerDoc = (mark: Doc, script: undefined | (() => ScriptField)) => { + return + } return
{!this.path ?
@@ -708,81 +614,44 @@ export class AudioBox extends ViewBoxAnnotatableComponent -
+
{this.waveform}
- {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => { - let rect; + {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => (!m.isLabel) ? (this.layoutDoc.hideMarkers) ? (null) : - rect = -
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} >
this.onPointerDown(e, m, true)}>
- + {markerDoc(m, this.rangeScript)}
this.onPointerDown(e, m, false)}>
: (this.layoutDoc.hideLabels) ? (null) : - rect = -
- -
; - return rect; - })} +
+ {markerDoc(m, this.labelScript)} +
+ )} {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); @@ -797,7 +666,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent e.stopPropagation()}> +
e.stopPropagation()}>
Doc.linkFollowHighlight(la1)} - onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} /> + onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
; })} {this._visible ? this.container : null} -
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} /> +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> {this.audio}
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
- {formatTime(Math.round(NumCast(this.dataDoc.duration)))} + {formatTime(Math.round(this.audioDuration))}
-- cgit v1.2.3-70-g09d2 From 3ca9aa0d915e9000f78d528fa59639512f8c4d25 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 11:37:31 -0400 Subject: more audioBox cleanup/fixes --- src/client/views/nodes/AudioBox.tsx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 0fb191c05..4c5d7fa0f 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -62,6 +62,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; + _audioRef = React.createRef(); _timeline: Opt; _duration = 0; _markerStart: number = 0; @@ -71,12 +72,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent = new Array(); - @observable _waveHeight: number | undefined = this.layoutDoc._height; + @observable _waveHeight: Opt = this.layoutDoc._height; @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @computed get audioState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.audioState as (undefined | "recording" | "paused" | "playing"); } set audioState(value) { this.dataDoc.audioState = value; } - public static SetScrubTime = (timeInMillisFrom1970: number) => { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; + public static SetScrubTime = action((timeInMillisFrom1970: number) => { AudioBox._scrubTime = 0; AudioBox._scrubTime = timeInMillisFrom1970; }); @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); } @computed get audioDuration() { return NumCast(this.dataDoc.duration); } async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); } @@ -155,6 +156,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); + setTimeout(() => { + const rect = this._timeline?.getBoundingClientRect(); + rect && this.update(rect.width, rect.height); + }, 1000); } // for updating the timecode @@ -541,12 +546,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent } - return
+ return
{!this.path ?
@@ -614,7 +620,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> {this.audio}
-- cgit v1.2.3-70-g09d2 From ab15a89319e53697a770929ed2ccd732c3d91ed2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 12:51:04 -0400 Subject: fixed audio box waveform to resize cleanly --- src/client/views/nodes/AudioBox.scss | 8 +++++ src/client/views/nodes/AudioBox.tsx | 63 +++--------------------------------- 2 files changed, 13 insertions(+), 58 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 973de979e..0d787d9af 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -181,6 +181,14 @@ z-index: -1000; bottom: 0; pointer-events: none; + div { + height: 100% !important; + width: 100% !important; + } + canvas { + height: 100% !important; + width: 100% !important; + } } .audiobox-linker, diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 4c5d7fa0f..bc89cb6f9 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -156,10 +156,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); - setTimeout(() => { - const rect = this._timeline?.getBoundingClientRect(); - rect && this.update(rect.width, rect.height); - }, 1000); } // for updating the timecode @@ -376,7 +372,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
+ }}>
; } // creates a new marker @@ -386,7 +382,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - const observer = new _global.ResizeObserver(action((entries: any) => { - Array.from(entries).map(e => e as any).filter(e => e.contentRect.width).forEach(e => { - this.update(e.contentRect.width, e.contentRect.height); - this._position = e.contentRect.width; - }) - })); - timeline && observer.observe(timeline); - - this._timeline = timeline; - } - - // update the width and height of the audio waveform - @action - update = (width: number, height: number) => { - const scaleCanvas = (canvas: HTMLCanvasElement) => { - let oldWidth = canvas.width; - let oldHeight = canvas.height; - canvas.style.height = `${height}`; - canvas.style.width = `${width}`; - - const ratio1 = oldWidth / window.innerWidth; - const ratio2 = oldHeight / window.innerHeight; - const context = canvas.getContext('2d'); - if (context) { - context.scale(ratio1, ratio2); - } - } - if (height) { - const height = 0.8 * NumCast(this.layoutDoc._height); - let canvas2 = this._timeline?.getElementsByTagName("canvas")[0]; - if (canvas2) { - scaleCanvas(canvas2); - } - - const canvas1 = this._timeline?.getElementsByTagName("canvas")[1]; - if (canvas1) { - scaleCanvas(canvas1); - - const parent = canvas1.parentElement; - if (parent) { - parent.style.width = `${width}`; - parent.style.height = `${height}`; - } - } - } - } - rangeScript = () => AudioBox.RangeScript; labelScript = () => AudioBox.LabelScript; @@ -585,8 +532,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent - } + scriptContext={this} />; + }; return
{!this.path ? @@ -613,7 +560,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
-
{ e.stopPropagation(); e.preventDefault(); }} +
{ e.stopPropagation(); e.preventDefault(); }} onPointerDown={e => { e.stopPropagation(); e.preventDefault(); -- cgit v1.2.3-70-g09d2 From 3ee0b9320fff9910c38bbef04e4866c6746316b8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 21:45:17 -0400 Subject: more audiobox cleanup. fixed dropping links onto audio box regions/labels. --- src/client/views/nodes/AudioBox.tsx | 125 +++++++++++++++--------------------- 1 file changed, 51 insertions(+), 74 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index bc89cb6f9..709422f35 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -25,6 +25,7 @@ import { List } from "../../../fields/List"; import { Scripting } from "../../util/Scripting"; import Waveform from "react-audio-waveform"; import axios from "axios"; +import { SnappingManager } from "../../util/SnappingManager"; const _global = (window /* browser */ || global /* node */) as any; declare class MediaRecorder { @@ -85,14 +86,21 @@ 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" })!; - } + // onClick play scripts + AudioBox.RangeScript = AudioBox.RangeScript || ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!; + AudioBox.LabelScript = AudioBox.LabelScript || ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!; + } - if (!AudioBox.LabelScript) { - AudioBox.LabelScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!; + getLinkData(l: Doc) { + 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); } + return { la1, la2, linkTime }; } componentWillUnmount() { @@ -110,7 +118,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (scrollLinkId) { DocListCast(this.dataDoc.links).filter(l => l[Id] === scrollLinkId).map(l => { - const linkTime = Doc.AreProtosEqual(l.anchor1 as Doc, this.dataDoc) ? NumCast(l.anchor1_timecode) : NumCast(l.anchor2_timecode); + const { linkTime } = this.getLinkData(l); setTimeout(() => { this.playFromTime(linkTime); Doc.linkFollowHighlight(l); }, 250); }); Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false); @@ -124,17 +132,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - let la1 = l.anchor1 as Doc; - let la2 = l.anchor2 as Doc; + DocListCast(this.dataDoc.links).map(l => { + let { la1, la2, linkTime } = this.getLinkData(l); 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); @@ -164,12 +165,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.dataDoc.duration = htmlEle.duration); DocListCast(this.dataDoc.links).map(l => { - let la1 = l.anchor1 as Doc; - let linkTime = NumCast(l.anchor2_timecode); - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - linkTime = NumCast(l.anchor1_timecode); - la1 = l.anchor2 as Doc; - } + const { la1, linkTime } = this.getLinkData(l); if (linkTime > NumCast(this.layoutDoc.currentTimecode) && linkTime < htmlEle.currentTime) { Doc.linkFollowHighlight(la1); } @@ -349,47 +345,33 @@ export class AudioBox extends ViewBoxAnnotatableComponent screen_delta / rect.width * this.audioDuration; this._markerStart = this._markerEnd = toTimeline(e.clientX - rect.x); - setupMoveUpEvents(this, e, action((e: PointerEvent) => { - this._visible = true; - this._markerEnd = toTimeline(e.clientX - rect.x); - if (this._markerEnd < this._markerStart) { - const tmp = this._markerStart; - this._markerStart = this._markerEnd; - this._markerEnd = tmp; - } - return false; - }), - action((e: PointerEvent, movement: number[]) => { - if (Math.abs(movement[0]) > 15) { - this.createNewMarker(this._markerStart, toTimeline(e.clientX - rect.x)); + setupMoveUpEvents(this, e, + action((e: PointerEvent) => { + this._visible = true; + this._markerEnd = toTimeline(e.clientX - rect.x); + if (this._markerEnd < this._markerStart) { + const tmp = this._markerStart; + this._markerStart = this._markerEnd; + this._markerEnd = tmp; } + return false; + }), + action((e: PointerEvent, movement: number[]) => { + (Math.abs(movement[0]) > 15) && this.createMarker(this._markerStart, toTimeline(e.clientX - rect.x)); this._visible = false; }), - emptyFunction); - } - // returns the selection container - @computed get container() { - return
; + (e: PointerEvent) => e.shiftKey && this.createMarker(this._ele!.currentTime) + ); } - // creates a new marker @action - createNewMarker(audioStart: number, audioEnd: number) { - const newMarker = Docs.Create.LabelDocument({ - title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, + createMarker(audioStart: number, audioEnd?: number) { + const marker = Docs.Create.LabelDocument({ + title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: audioEnd === undefined, useLinkSmallAnchor: true, hideLinkButton: true, audioStart, audioEnd, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }); - this.addMark(newMarker); - } - - // adds an annotation marker or label - @action - addMark(marker: Doc) { - marker.data = ""; + marker.data = ""; // clears out the label's text so that only its border will display if (this.dataDoc[this.annotationKey]) { this.dataDoc[this.annotationKey].push(marker); } else { @@ -403,10 +385,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent screen_delta / rect.width * this.audioDuration; - setupMoveUpEvents(this, e, () => { - this.changeMarker(this._currMarker, toTimeline(e.clientX - rect.x)); - return false; - }, + setupMoveUpEvents(this, e, + () => { + this.changeMarker(this._currMarker, toTimeline(e.clientX - rect.x)); + return false; + }, () => this._ele!.currentTime = this.layoutDoc.currentTimecode = toTimeline(e.clientX - rect.x), emptyFunction); } @@ -462,6 +445,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent; + } + // returns the audio waveform @computed get waveform() { return AudioBox.LabelScript; render() { - const interactive = this.active() ? "-interactive" : ""; + const interactive = SnappingManager.GetIsDragging() || this.active() ? "-interactive" : ""; this._first = true; // for indicating the first marker that is rendered this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording const markerDoc = (mark: Doc, script: undefined | (() => ScriptField)) => { @@ -562,8 +552,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{ e.stopPropagation(); e.preventDefault(); }} onPointerDown={e => { - e.stopPropagation(); - e.preventDefault(); if (e.button === 0 && !e.ctrlKey) { const rect = (e.target as any).getBoundingClientRect(); @@ -575,9 +563,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{this.waveform} @@ -605,15 +590,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent )} {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); - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - la1 = l.anchor2 as Doc; - la2 = l.anchor1 as Doc; - linkTime = NumCast(l.anchor1_timecode); - } - + let { la1, la2, linkTime } = this.getLinkData(l); if (la2.audioStart && !la2.audioEnd) { linkTime = NumCast(la2.audioStart); } @@ -639,7 +616,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
; })} - {this._visible ? this.container : null} + {this._visible ? this.selectionContainer : null}
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> {this.audio} -- cgit v1.2.3-70-g09d2 From dc0ffc050b5b11e345245927f3d8a813937e588d Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 22:48:26 -0400 Subject: starting to fix link following behavior to audio regions. --- src/client/util/DocumentManager.ts | 2 +- src/client/views/linking/LinkEditor.tsx | 6 +- src/client/views/nodes/AudioBox.scss | 5 + src/client/views/nodes/AudioBox.tsx | 256 ++++++++++++++++---------------- 4 files changed, 140 insertions(+), 129 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 523dbfca0..bd57e7f48 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -152,7 +152,7 @@ export class DocumentManager { const first = getFirstDocView(annotatedDoc); if (first) { annotatedDoc = first.props.Document; - docView?.props.focus(annotatedDoc, false); + first.props.focus(annotatedDoc, false); } } if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 5832a2181..3ef391a5d 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -355,11 +355,11 @@ export class LinkEditor extends React.Component { this.openDropdown = !this.openDropdown; } - @undoBatch @action - changeFollowBehavior = (follow: string) => { + @undoBatch + changeFollowBehavior = action((follow: string) => { this.openDropdown = false; Doc.GetProto(this.props.linkDoc).followLinkLocation = follow; - } + }) @computed get followingDropdown() { diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 0d787d9af..c80e3af24 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -8,6 +8,11 @@ position: relative; cursor: default; + .audiobox-inner { + width:100%; + height: 100%; + } + .audiobox-buttons { display: flex; width: 100%; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 709422f35..0ea624edf 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -128,37 +128,41 @@ 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(this.dataDoc.links).map(l => { - let { la1, la2, linkTime } = this.getLinkData(l); - if (la1 === sel || la2 === sel) { // if the selected document is linked to this audio - let endTime; - if (la2.audioStart) linkTime = NumCast(la2.audioStart); - if (la1.audioStart) linkTime = NumCast(la1.audioStart); - - if (la1.audioEnd) endTime = NumCast(la1.audioEnd); - if (la2.audioEnd) endTime = NumCast(la2.audioEnd); - - if (linkTime) { - link = true; - this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && (endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime)); - } - } - }); - } - - // for links created during recording - if (!link) { - this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); - this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); + if (this.layoutDoc.playOnSelect) { + const sel = selected.length ? selected[0].props.Document : undefined; + const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(l), false); + // for links created during recording + if (!link) { + this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); + this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); + } } }); this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); } + playLink = (doc: Doc) => { + let link = false; + !Doc.AreProtosEqual(doc, this.props.Document) && DocListCast(this.props.Document.links).forEach(l => { + if (l.anchor1 === doc || l.anchor2 === doc) { + const { la1, la2, linkTime } = this.getLinkData(l); + let startTime = linkTime; + if (la2.audioStart) startTime = NumCast(la2.audioStart); + if (la1.audioStart) startTime = NumCast(la1.audioStart); + + let endTime; + if (la1.audioEnd) endTime = NumCast(la1.audioEnd); + if (la2.audioEnd) endTime = NumCast(la2.audioEnd); + + if (startTime) { + link = true; + this.recordingStart && (endTime ? this.playFrom(startTime, endTime) : this.playFrom(startTime)); + } + } + }); + return link; + } + // for updating the timecode timecodeChanged = () => { const htmlEle = this._ele; @@ -511,6 +515,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent ScriptField)) => { return this.playLink(mark)} pointerEvents={true} NativeHeight={returnZero} NativeWidth={returnZero} @@ -524,112 +529,113 @@ export class AudioBox extends ViewBoxAnnotatableComponent; }; - return
- {!this.path ? -
-
- -
- {this.audioState === "recording" ? -
e.stopPropagation()}> -
- -
-
- -
-
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+ return
+
+ {!this.path ? +
+
+
- : - } -
: -
-
-
-
-
{ e.stopPropagation(); e.preventDefault(); }} - onPointerDown={e => { - if (e.button === 0 && !e.ctrlKey) { - const rect = (e.target as any).getBoundingClientRect(); - - if (e.target !== this._audioRef.current) { - const wasPaused = this.audioState === "paused"; - this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * this.audioDuration; - wasPaused && this.pause(); +
: +
+
+
+
+
{ e.stopPropagation(); e.preventDefault(); }} + onPointerDown={e => { + if (e.button === 0 && !e.ctrlKey) { + const rect = (e.target as any).getBoundingClientRect(); + + if (e.target !== this._audioRef.current) { + const wasPaused = this.audioState === "paused"; + this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * this.audioDuration; + wasPaused && this.pause(); + } + + this.onPointerDownTimeline(e); + } + }}> +
+ {this.waveform} +
+ {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => + (!m.isLabel) ? + (this.layoutDoc.hideMarkers) ? (null) : +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} > +
this.onPointerDown(e, m, true)}>
+ {markerDoc(m, this.rangeScript)} +
this.onPointerDown(e, m, false)}>
+
+ : + (this.layoutDoc.hideLabels) ? (null) : +
+ {markerDoc(m, this.labelScript)} +
+ )} + {DocListCast(this.dataDoc.links).map((l, i) => { + const { la1, la2, linkTime } = this.getLinkData(l); + let startTime = linkTime; + if (la2.audioStart && !la2.audioEnd) { + startTime = NumCast(la2.audioStart); } - this.onPointerDownTimeline(e); - } - }}> -
- {this.waveform} + return !linkTime ? (null) : +
e.stopPropagation()}> + +
Doc.linkFollowHighlight(la1)} + onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(startTime); e.stopPropagation(); e.preventDefault(); } }} /> +
; + })} + {this._visible ? this.selectionContainer : null} + +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> + {this.audio} +
+
+ {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} +
+
+ {formatTime(Math.round(this.audioDuration))}
- {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => - (!m.isLabel) ? - (this.layoutDoc.hideMarkers) ? (null) : -
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} > -
this.onPointerDown(e, m, true)}>
- {markerDoc(m, this.rangeScript)} -
this.onPointerDown(e, m, false)}>
-
- : - (this.layoutDoc.hideLabels) ? (null) : -
- {markerDoc(m, this.labelScript)} -
- )} - {DocListCast(this.dataDoc.links).map((l, i) => { - let { la1, la2, linkTime } = this.getLinkData(l); - if (la2.audioStart && !la2.audioEnd) { - linkTime = NumCast(la2.audioStart); - } - - return !linkTime ? (null) : -
e.stopPropagation()}> - -
Doc.linkFollowHighlight(la1)} - onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} /> -
; - })} - {this._visible ? this.selectionContainer : null} - -
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> - {this.audio} -
-
- {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} -
-
- {formatTime(Math.round(this.audioDuration))}
-
- } + }
; } } -- cgit v1.2.3-70-g09d2 From 1d2851b237fd41f8a8726244b095986699f513a5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 23:09:49 -0400 Subject: fixed playing audio on link follow when audio opens on right or in tab --- src/client/views/linking/LinkMenuItem.tsx | 9 ++++++++- src/client/views/nodes/AudioBox.tsx | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index b95fccf2a..21c666a4d 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -162,7 +162,14 @@ export class LinkMenuItem extends React.Component { } if (linkDoc.followLinkLocation && linkDoc.followLinkLocation !== "Default") { - this.props.addDocTab(this.props.destinationDoc, StrCast(linkDoc.followLinkLocation)); + const annotationOn = this.props.destinationDoc.annotationOn as Doc; + this.props.addDocTab(annotationOn instanceof Doc ? annotationOn : this.props.destinationDoc, StrCast(linkDoc.followLinkLocation)); + if (annotationOn) { + setTimeout(() => { + const dv = DocumentManager.Instance.getFirstDocumentView(this.props.destinationDoc); + dv?.props.focus(this.props.destinationDoc, false); + }); + } } else { DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 0ea624edf..d689aeadc 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -195,7 +195,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.playFrom(seekTimeInSeconds, endTime), 500); + } else if (this._ele && AudioBox.Enabled) { if (seekTimeInSeconds < 0) { if (seekTimeInSeconds > -1) { setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000); -- cgit v1.2.3-70-g09d2 From b096129d54238bc4cea735cd2db8e5f3e94613b7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 23:23:06 -0400 Subject: fixed playing audio links on select. --- src/client/views/nodes/AudioBox.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes/AudioBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index d689aeadc..289388320 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -128,14 +128,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent SelectionManager.SelectedDocuments(), selected => { - if (this.layoutDoc.playOnSelect) { - const sel = selected.length ? selected[0].props.Document : undefined; - const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(l), false); - // for links created during recording - if (!link) { - this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); - this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); - } + const sel = selected.length ? selected[0].props.Document : undefined; + const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(sel), false); + // for links created during recording + if (!link) { + this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); + this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); } }); this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); -- cgit v1.2.3-70-g09d2