aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/AudioBox.scss15
-rw-r--r--src/client/views/nodes/AudioBox.tsx118
-rw-r--r--src/server/index.ts1
3 files changed, 110 insertions, 24 deletions
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 306062ced..c0743933e 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -150,6 +150,21 @@
z-index: 1000;
overflow: hidden;
+ .audiobox-container {
+ position: absolute;
+ width: 10px;
+ top: 2.5%;
+ height: 0px;
+ background: lightblue;
+ border-radius: 5px;
+ // box-shadow: black 2px 2px 1px;
+ opacity: 0.3;
+ z-index: 500;
+ border-style: solid;
+ border-color: darkblue;
+ border-width: 1px;
+ }
+
.audiobox-current {
width: 1px;
height: 100%;
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index eba1046b2..4805b8643 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";
@@ -60,20 +60,22 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
_start: number = 0;
_hold: boolean = false;
_left: boolean = false;
- _markers: Array<any> = [];
_first: boolean = false;
_dragging = false;
_count: Array<any> = [];
_timeline: Opt<HTMLDivElement>;
_duration = 0;
-
+ _containerX: number = 0;
+ _invertedX: boolean = false;
private _isPointerDown = false;
private _currMarker: any;
+ @observable _visible: boolean = false;
+ @observable _currX: number = 0;
@observable _position: number = 0;
@observable _buckets: Array<number> = new Array<number>();
- @observable private _height: number = NumCast(this.layoutDoc._height);
+ @observable _waveHeight: number | undefined = 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"); }
@@ -354,6 +356,68 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
return (this._pauseEnd - this._pauseStart);
}
+ // starting the drag event for marker resizing
+ @action
+ onPointerDownTimeline = (e: React.PointerEvent): void => {
+ 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);
+ }
+
+ // 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);
+ }
+
+ // 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();
+
+ this._currX = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+
+ (this._currX - this._containerX < 0) ? this._invertedX = true : this._invertedX = false;
+ }
+
+ // returns the selection container
+ @computed get container() {
+ return <div className="audiobox-container" style={{ left: !this._invertedX ? `${NumCast(this._containerX) / NumCast(this.dataDoc.duration, 1) * 100}%` : `${this._currX / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${Math.abs(this._containerX - this._currX) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: "100%", top: "0%" }}></div>
+ }
+
// creates a new label
@action
newMarker(marker: Doc) {
@@ -375,7 +439,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
@action
end(marker: number) {
this._hold = false;
- const newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
+ const newMarker = this._invertedX ?
+ Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: marker, audioEnd: this._start, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document })
+ :
+ Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
newMarker.data = "";
if (this.dataDoc[this.annotationKey]) {
this.dataDoc[this.annotationKey].push(newMarker);
@@ -497,9 +564,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
@computed get waveform() {
return <Waveform
color={"darkblue"}
- height={this._height}
+ height={this._waveHeight}
barWidth={0.1}
- // pos={this.layoutDoc.currentTimecode}
+ // pos={this.layoutDoc.currentTimecode} need to correctly resize parent to make this work (not very necessary for function)
pos={this.dataDoc.duration}
duration={this.dataDoc.duration}
peaks={this._buckets.length === 100 ? this._buckets : undefined}
@@ -559,12 +626,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
@action
update = (width: number, height: number) => {
if (height) {
- this._height = 0.8 * NumCast(this.layoutDoc._height);
- const canvas2 = document.getElementsByTagName("canvas")[0];
+ const height = 0.8 * NumCast(this.layoutDoc._height);
+ let canvas2 = document.getElementsByTagName("canvas")[0];
if (canvas2) {
- const oldWidth = canvas2.width;
- const oldHeight = canvas2.height;
- canvas2.style.height = `${this._height}`;
+ let oldWidth = canvas2.width;
+ let oldHeight = canvas2.height;
+ canvas2.style.height = `${height}`;
canvas2.style.width = `${width}`;
const ratio1 = oldWidth / window.innerWidth;
@@ -579,7 +646,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
if (canvas1) {
const oldWidth = canvas1.width;
const oldHeight = canvas1.height;
- canvas1.style.height = `${this._height}`;
+ canvas1.style.height = `${height}`;
canvas1.style.width = `${width}`;
const ratio1 = oldWidth / window.innerWidth;
@@ -592,7 +659,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
const parent = canvas1.parentElement;
if (parent) {
parent.style.width = `${width}`;
- parent.style.height = `${this._height}`;
+ parent.style.height = `${height}`;
}
}
}
@@ -641,23 +708,26 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
if (e.button === 0 && !e.ctrlKey) {
const rect = (e.target as any).getBoundingClientRect();
+
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();
}
+
+ this.onPointerDownTimeline(e);
}
- if (e.button === 0 && e.altKey) {
+ if (e.button === 0 && e.shiftKey) {
this.newMarker(Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart)`) as any, useLinkSmallAnchor: true, hideLinkButton: true, isLabel: true, audioStart: this._ele!.currentTime, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }));
}
- if (e.button === 0 && e.shiftKey) {
- 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);
- }
+ // 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);
+ // }
}}>
- <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
+ <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px", pointerEvents: "none" }}>
{this.waveform}
</div>
{DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => {
@@ -669,8 +739,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
title={`${formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${formatTime(Math.round(NumCast(m.audioEnd)))}`}
style={{
left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`,
- width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`,
- top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%`
+ top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%`,
+ width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`
}}
onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} >
<div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
@@ -747,6 +817,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
</div>;
})}
+ {this._visible ? this.container : null}
+
<div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} />
{this.audio}
</div>
diff --git a/src/server/index.ts b/src/server/index.ts
index 97a90825d..c4e6be8a2 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -103,7 +103,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));
};