aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-08-09 11:37:55 -0400
committerGitHub <noreply@github.com>2020-08-09 11:37:55 -0400
commit4ea8053fdcc2dd8862bd3e5b2995f89c255157a2 (patch)
treec358b6a83ecb639e3e18e02d0f7ebe0fb0d46613 /src
parent9f4a7ec5f79d9dec3a0ffb0b633197216cbefec8 (diff)
parent3ca9aa0d915e9000f78d528fa59639512f8c4d25 (diff)
Merge pull request #519 from browngraphicslab/new_audio
New audio
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts4
-rw-r--r--src/client/views/nodes/AudioBox.scss18
-rw-r--r--src/client/views/nodes/AudioBox.tsx341
-rw-r--r--src/server/index.ts1
4 files changed, 163 insertions, 201 deletions
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 306062ced..973de979e 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%;
@@ -164,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 eba1046b2..4c5d7fa0f 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";
@@ -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);
@@ -60,26 +58,28 @@ 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> = [];
+ _audioRef = React.createRef<HTMLDivElement>();
_timeline: Opt<HTMLDivElement>;
_duration = 0;
-
- private _isPointerDown = false;
+ _markerStart: number = 0;
private _currMarker: any;
+ @observable _visible: boolean = false;
+ @observable _markerEnd: number = 0;
@observable _position: number = 0;
@observable _buckets: Array<number> = new Array<number>();
- @observable private _height: number = NumCast(this.layoutDoc._height);
+ @observable _waveHeight: Opt<number> = 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); }
constructor(props: Readonly<FieldViewProps>) {
@@ -135,21 +135,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
la2 = l.anchor1 as Doc;
linkTime = NumCast(l.anchor1_timecode);
}
- if (la2.audioStart) {
- linkTime = NumCast(la2.audioStart);
- }
-
- if (la1.audioStart) {
- linkTime = NumCast(la1.audioStart);
- }
+ if (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 (la1.audioEnd) endTime = NumCast(la1.audioEnd);
+ if (la2.audioEnd) endTime = NumCast(la2.audioEnd);
if (linkTime) {
link = true;
@@ -166,6 +156,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
}
});
this._scrubbingDisposer = reaction(() => 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
@@ -201,7 +195,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
// play back the audio from time
@action
- playFrom = (seekTimeInSeconds: number, endTime: number = this.dataDoc.duration) => {
+ playFrom = (seekTimeInSeconds: number, endTime: number = this.audioDuration) => {
let play;
clearTimeout(play);
this._duration = endTime - seekTimeInSeconds;
@@ -216,7 +210,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
this._ele.currentTime = seekTimeInSeconds;
this._ele.play();
runInAction(() => 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 {
@@ -228,11 +222,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
// update the recording time
updateRecordTime = () => {
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;
}
}
@@ -351,115 +344,96 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
// return the total time paused to update the correct time
@computed get pauseTime() {
- return (this._pauseEnd - this._pauseStart);
+ return this._pauseEnd - this._pauseStart;
}
- // creates a new label
+ // starting the drag event for marker resizing
@action
- newMarker(marker: Doc) {
- marker.data = "";
- if (this.dataDoc[this.annotationKey]) {
- this.dataDoc[this.annotationKey].push(marker);
- } else {
- this.dataDoc[this.annotationKey] = new List<Doc>([marker]);
- }
+ onPointerDownTimeline = (e: React.PointerEvent): void => {
+ const rect = (e.target as any).getBoundingClientRect();
+ 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);
}
-
- // the starting time of the marker
- start(startingPoint: number) {
- this._hold = true;
- this._start = startingPoint;
+ // returns the selection container
+ @computed get container() {
+ return <div className="audiobox-container" style={{
+ left: `${NumCast(this._markerStart) / this.audioDuration * 100}%`,
+ width: `${Math.abs(this._markerStart - this._markerEnd) / this.audioDuration * 100}%`, height: "100%", top: "0%"
+ }}></div>
}
// creates a new marker
@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 });
- newMarker.data = "";
+ 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);
+ }
+
+ // adds an annotation marker or label
+ @action
+ addMark(marker: Doc) {
+ marker.data = "";
if (this.dataDoc[this.annotationKey]) {
- this.dataDoc[this.annotationKey].push(newMarker);
+ this.dataDoc[this.annotationKey].push(marker);
} else {
- this.dataDoc[this.annotationKey] = new List<Doc>([newMarker]);
+ this.dataDoc[this.annotationKey] = new List<Doc>([marker]);
}
-
- 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
@@ -484,7 +458,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) {
this._count[i][1] = max;
}
-
}
if (this.dataDoc.markerAmount < max) {
@@ -497,11 +470,11 @@ 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.dataDoc.duration}
- duration={this.dataDoc.duration}
+ // pos={this.layoutDoc.currentTimecode} need to correctly resize parent to make this work (not very necessary for function)
+ pos={this.audioDuration}
+ duration={this.audioDuration}
peaks={this._buckets.length === 100 ? this._buckets : undefined}
progressColor={"blue"} />;
}
@@ -545,10 +518,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
// for updating the width and height of the waveform with timeline ref
timelineRef = (timeline: HTMLDivElement) => {
const observer = new _global.ResizeObserver(action((entries: any) => {
- for (const entry of entries) {
- 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);
@@ -558,58 +531,64 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
// 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) {
- this._height = 0.8 * NumCast(this.layoutDoc._height);
- const canvas2 = document.getElementsByTagName("canvas")[0];
+ const height = 0.8 * NumCast(this.layoutDoc._height);
+ let canvas2 = this._timeline?.getElementsByTagName("canvas")[0];
if (canvas2) {
- const oldWidth = canvas2.width;
- const oldHeight = canvas2.height;
- canvas2.style.height = `${this._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];
+ const canvas1 = this._timeline?.getElementsByTagName("canvas")[1];
if (canvas1) {
- const oldWidth = canvas1.width;
- const oldHeight = canvas1.height;
- canvas1.style.height = `${this._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) {
parent.style.width = `${width}`;
- parent.style.height = `${this._height}`;
+ parent.style.height = `${height}`;
}
}
}
}
rangeScript = () => 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
- return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}>
+ const markerDoc = (mark: Doc, script: undefined | (() => ScriptField)) => {
+ return <DocumentView {...this.props}
+ Document={mark}
+ pointerEvents={true}
+ NativeHeight={returnZero}
+ NativeWidth={returnZero}
+ rootSelected={returnFalse}
+ LayoutTemplate={undefined}
+ ContainingCollectionDoc={this.props.Document}
+ removeDocument={this.removeDocument}
+ parentActive={returnTrue}
+ onClick={this.layoutDoc.playOnClick ? script : undefined}
+ ignoreAutoHeight={false}
+ bringToFront={emptyFunction}
+ scriptContext={this} />
+ }
+ return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu} onClick={!this.path ? this.recordClick : undefined}
+ style={{ pointerEvents: !interactive ? "none" : undefined }}>
{!this.path ?
<div className="audiobox-buttons">
<div className="audiobox-dictation" onClick={this.onFile}>
@@ -641,78 +620,44 @@ 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")) {
+ if (e.target !== this._audioRef.current) {
const wasPaused = this.audioState === "paused";
- this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+ this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * this.audioDuration;
wasPaused && this.pause();
}
- }
- if (e.button === 0 && e.altKey) {
- 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 }));
- }
+ this.onPointerDownTimeline(e);
+ }
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.addMark(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 }));
}
}}>
- <div className="waveform" id="waveform" style={{ height: `${100}%`, width: "100%", bottom: "0px" }}>
+ <div className="waveform">
{this.waveform}
</div>
- {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 =
- <div key={i} id={"audiobox-marker-container1"} className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"}
+ <div className={`audiobox-marker-${this.props.PanelHeight() < 32 ? "mini" : ""}container1`} key={i}
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}%`
+ left: `${NumCast(m.audioStart) / this.audioDuration * 100}%`,
+ top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%`,
+ width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / this.audioDuration * 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>
- <DocumentView {...this.props}
- Document={m}
- pointerEvents={true}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- rootSelected={returnFalse}
- LayoutTemplate={undefined}
- ContainingCollectionDoc={this.props.Document}
- removeDocument={this.removeDocument}
- parentActive={returnTrue}
- onClick={this.layoutDoc.playOnClick ? this.rangeScript : undefined}
- ignoreAutoHeight={false}
- bringToFront={emptyFunction}
- scriptContext={this} />
+ {markerDoc(m, this.rangeScript)}
<div className="resizer" onPointerDown={e => this.onPointerDown(e, m, false)}></div>
</div>
:
(this.layoutDoc.hideLabels) ? (null) :
- rect =
- <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={i} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
- <DocumentView {...this.props}
- Document={m}
- pointerEvents={true}
- NativeHeight={returnZero}
- NativeWidth={returnZero}
- rootSelected={returnFalse}
- LayoutTemplate={undefined}
- ContainingCollectionDoc={this.props.Document}
- removeDocument={this.removeDocument}
- parentActive={returnTrue}
- onClick={this.layoutDoc.playOnClick ? this.labelScript : undefined}
- ignoreAutoHeight={false}
- bringToFront={emptyFunction}
- scriptContext={this} />
- </div>;
- return rect;
- })}
+ <div className={`audiobox-marker-${this.props.PanelHeight() < 32 ? "mini" : ""}container`} key={i}
+ style={{ left: `${NumCast(m.audioStart) / this.audioDuration * 100}%` }}>
+ {markerDoc(m, this.labelScript)}
+ </div>
+ )}
{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);
@@ -727,7 +672,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
}
return !linkTime ? (null) :
- <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }} onClick={e => e.stopPropagation()}>
+ <div className={`audiobox-marker-${this.props.PanelHeight() < 32 ? "mini" : ""}container`} key={l[Id]} style={{ left: `${linkTime / this.audioDuration * 100}%` }} onClick={e => e.stopPropagation()}>
<DocumentView {...this.props}
Document={l}
NativeHeight={returnZero}
@@ -744,17 +689,19 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)}
/>
<div key={i} className={`audiobox-marker`} onPointerEnter={() => Doc.linkFollowHighlight(la1)}
- onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
+ onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
</div>;
})}
- <div className="audiobox-current" id="current" onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%`, pointerEvents: "none" }} />
+ {this._visible ? this.container : null}
+
+ <div className="audiobox-current" ref={this._audioRef} onClick={e => { e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} />
{this.audio}
</div>
<div className="current-time">
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
</div>
<div className="total-time">
- {formatTime(Math.round(NumCast(this.dataDoc.duration)))}
+ {formatTime(Math.round(this.audioDuration))}
</div>
</div>
</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));
};