From 502981833ef7f9e8179bf9c487b1e35404c6d4e1 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Tue, 28 Jul 2020 15:08:56 -0700 Subject: fix recursion bug and make link turn blue --- .../views/nodes/formattedText/FormattedTextBox.tsx | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 6b6fc5da2..b1d9be73b 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1295,6 +1295,30 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } e.stopPropagation(); if (e.key === "Tab" || e.key === "Enter") { + // console.log(this._recording); + // if (this._editorView) { + // const state = this._editorView.state; + // const now = Date.now(); + // let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) }); + // if (!this._break && state.selection.to !== state.selection.from) { + // for (let i = state.selection.from; i <= state.selection.to; i++) { + // const pos = state.doc.resolve(i); + // const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark); + // if (um) { + // mark = um; + // break; + // } + // } + // } + // const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime(); + // this._break = false; + // let value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000; + // //let value = "[0:02]"; + // const from = state.selection.from; + // const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); + + // this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1))); + // } e.preventDefault(); } if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) { -- cgit v1.2.3-70-g09d2 From e25afb5fe507ff13cb6e863c07032d9d9dcc864b Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Mon, 3 Aug 2020 12:37:32 -0700 Subject: added timestamps and added delete for markers and changed the way markers are rendered --- src/client/documents/Documents.ts | 2 +- src/client/views/nodes/AudioBox.scss | 1 + src/client/views/nodes/AudioBox.tsx | 113 ++++++++++++------- .../views/nodes/formattedText/FormattedTextBox.tsx | 124 ++++++++++++++++----- 4 files changed, 172 insertions(+), 68 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 88f470576..402f3e82c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -628,7 +628,7 @@ export namespace Docs { } export function AudioDocument(url: string, options: DocumentOptions = {}) { - const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { ...options }); // hideLinkButton: false, useLinkSmallAnchor: false, + const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { useLinkSmallAnchor: true, ...options }); // hideLinkButton: false, useLinkSmallAnchor: false, Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'"); return instance; } diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 35ab5da8b..0ea4b37cb 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -148,6 +148,7 @@ width: 100%; height: 100%; overflow: hidden; + z-index: 0; } .audiobox-linker, diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 3d1932883..7c90547ef 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -75,6 +75,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _first: boolean = false; _buckets: Array = new Array(); + _count: Array = []; private _isPointerDown = false; private _currMarker: any; @@ -516,53 +517,74 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + const increment = NumCast(this.layoutDoc.duration) / 500; + this._count = []; + for (let i = 0; i < 500; i++) { + this._count.push([increment * i, 0]) + } + + } + // Probably need a better way to format - isOverlap = (m: any, i: number) => { - console.log("called"); - let counter = 0; + // isOverlap = (m: any, i: number) => { + // console.log("called"); + // let counter = 0; + // if (this._first) { + // this._markers = []; + // this._first = false; + // } + // for (let i = 0; i < this._markers.length; i++) { + // if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) { + // counter++; + // console.log(counter); + // } + // } + + // if (this.dataDoc.markerAmount < counter) { + // this.dataDoc.markerAmount = counter; + // } + + // this._markers.push(m); + + // return counter; + // } + + isOverlap = (m: any) => { if (this._first) { - this._markers = []; this._first = false; - } - for (let i = 0; i < this._markers.length; i++) { - if ((m.audioEnd > this._markers[i].audioStart && m.audioStart < this._markers[i].audioEnd)) { - counter++; - console.log(counter); - } + this.markers(); + console.log(this._count); } - if (this.dataDoc.markerAmount < counter) { - this.dataDoc.markerAmount = counter; - } - this._markers.push(m); + let max = 0 - return counter; - } + for (let i = 0; i < 500; i++) { + if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) { + this._count[i][1]++; - // isOverlap = (m: any) => { - // if (this._markers.length < 1) { - // this._markers = new Array(Math.round(this.dataDoc.duration)).fill(0); - // } - // console.log(this._markers); - // let max = 0 + if (this._count[i][1] > max) { + max = this._count[i][1]; + } + } - // for (let i = Math.round(m.audioStart); i <= Math.round(m.audioEnd); i++) { - // this._markers[i] = this._markers[i] + 1; - // console.log(this._markers[i]); - // if (this._markers[i] > max) { - // max = this._markers[i]; - // } - // } + } - // console.log(max); - // if (this.dataDoc.markerAmount < max) { - // this.dataDoc.markerAmount = max; - // } - // return max - // } + for (let i = 0; i < 500; i++) { + if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) { + this._count[i][1] = max; + } + + } + + if (this.dataDoc.markerAmount < max) { + this.dataDoc.markerAmount = max; + } + return max - 1 + } formatTime = (time: number) => { const hours = Math.floor(time / 60 / 60); @@ -609,6 +631,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent -
+
{console.log(this.peaks)}
@@ -690,7 +719,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)}>
- {this.formatTime(Math.round(NumCast(this.layoutDoc.duration)))} + {this.formatTime(Math.round(NumCast(this.dataDoc.duration)))}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b1d9be73b..91940466f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -2,7 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faEdit, faSmile, faTextHeight, faUpload } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEqual } from "lodash"; -import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { baseKeymap, selectAll } from "prosemirror-commands"; import { history } from "prosemirror-history"; @@ -93,6 +93,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp private _undoTyping?: UndoManager.Batch; private _disposers: { [name: string]: IReactionDisposer } = {}; private _dropDisposer?: DragManager.DragDropDisposer; + private _first: Boolean = true; + private _recordingStart: number = 0; + private _currentTime: number = 0; + private _linkTime: number | null = null; + private _pause: boolean = false; @computed get _recording() { return this.dataDoc.audioState === "recording"; } set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; } @@ -140,6 +145,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp super(props); FormattedTextBox.Instance = this; this.updateHighlights(); + this._recordingStart = Date.now(); + this.layoutDoc._timeStampOnEnter = true; } public get CurrentDiv(): HTMLDivElement { return this._ref.current!; } @@ -197,9 +204,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } dispatchTransaction = (tx: Transaction) => { + let timeStamp; + clearTimeout(timeStamp); + console.log("hi"); if (this._editorView) { + const metadata = tx.selection.$from.marks().find((m: Mark) => m.type === schema.marks.metadata); if (metadata) { + const range = tx.selection.$from.blockRange(tx.selection.$to); let text = range ? tx.doc.textBetween(range.start, range.end) : ""; let textEndSelection = tx.selection.to; @@ -221,6 +233,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.dataDoc[key] = value; } } + const state = this._editorView.state.apply(tx); this._editorView.updateState(state); (tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks); @@ -234,19 +247,33 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const json = JSON.stringify(state.toJSON()); let unchanged = true; const effectiveAcl = GetEffectiveAcl(this.dataDoc); + + if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) { this._applyingChange = true; (curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()))); if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) if (json.replace(/"selection":.*/, "") !== curLayout?.Data.replace(/"selection":.*/, "")) { + console.log("type"); + if (!this._pause && !this.layoutDoc._timeStampOnEnter) { + console.log("started"); + timeStamp = setTimeout(() => this.pause(), 10 * 1000); + } + + if (this._pause) { + this._pause = false; + this.insertTime(); + } !curText && tx.storedMarks?.map(m => m.type.name === "pFontSize" && (Doc.UserDoc().fontSize = this.layoutDoc._fontSize = m.attrs.fontSize)); !curText && tx.storedMarks?.map(m => m.type.name === "pFontFamily" && (Doc.UserDoc().fontFamily = this.layoutDoc._fontFamily = m.attrs.fontFamily)); this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText); this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: curText }); unchanged = false; + } + } else { // if we've deleted all the text in a note driven by a template, then restore the template data this.dataDoc[this.props.fieldKey] = undefined; this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((curProto || curTemp).Data))); @@ -260,6 +287,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } } else { + const json = JSON.parse(Cast(this.dataDoc[this.fieldKey], RichTextField)?.Data!); json.selection = state.toJSON().selection; this._editorView.updateState(EditorState.fromJSON(this.config, json)); @@ -267,6 +295,66 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + pause = () => this._pause = true; + + formatTime = (time: number) => { + const hours = Math.floor(time / 60 / 60); + const minutes = Math.floor(time / 60) - (hours * 60); + const seconds = time % 60; + + return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0'); + } + + insertTime = () => { + let linkTime; + if (this._first) { + this._first = false; + DocListCast(this.dataDoc.links).map((l, i) => { + let la1 = l.anchor1 as Doc; + let la2 = l.anchor2 as Doc; + this._linkTime = NumCast(l.anchor2_timecode); + if (Doc.AreProtosEqual(la2, this.dataDoc)) { + la1 = l.anchor2 as Doc; + la2 = l.anchor1 as Doc; + this._linkTime = NumCast(l.anchor1_timecode); + } + + }) + + + + } + this._currentTime = Date.now(); + let time; + console.log(this._linkTime); + this._linkTime ? time = this.formatTime(Math.round(this._linkTime + this._currentTime / 1000 - this._recordingStart / 1000)) : time = null; + + if (this._editorView) { + const state = this._editorView.state; + const now = Date.now(); + let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) }); + if (!this._break && state.selection.to !== state.selection.from) { + for (let i = state.selection.from; i <= state.selection.to; i++) { + const pos = state.doc.resolve(i); + const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark); + if (um) { + mark = um; + break; + } + } + } + if (time) { + let value = ""; + this._break = false; + value = this.layoutDoc._timeStampOnEnter ? "[" + time + "] " : "\n" + "[" + time + "] "; + console.log(value); + const from = state.selection.from; + const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); + this._editorView.dispatch(this._editorView.state.tr.insertText(value)); + } + } + } + updateTitle = () => { if ((this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.rootDoc.customTitle) { @@ -501,6 +589,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp uicontrols.push({ description: `${this.layoutDoc._showSidebar ? "Hide" : "Show"} Sidebar`, event: () => this.layoutDoc._showSidebar = !this.layoutDoc._showSidebar, icon: "expand-arrows-alt" }); uicontrols.push({ description: `${this.layoutDoc._showAudio ? "Hide" : "Show"} Dictation Icon`, event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" }); uicontrols.push({ description: "Show Highlights...", noexpand: true, subitems: highlighting, icon: "hand-point-right" }); + uicontrols.push({ description: `Create TimeStamp When ${this.layoutDoc._timeStampOnEnter ? "Pause" : "Enter"}`, event: () => this.layoutDoc._timeStampOnEnter = !this.layoutDoc._timeStampOnEnter, icon: "expand-arrows-alt" }); !Doc.UserDoc().noviceMode && uicontrols.push({ description: "Broadcast Message", event: () => DocServer.GetRefField("rtfProto").then(proto => proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.rootDoc[this.fieldKey], RichTextField)?.Text)), icon: "expand-arrows-alt" @@ -594,6 +683,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime(); this._break = false; value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value; + console.log(value); const from = state.selection.from; const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1))); @@ -1295,30 +1385,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } e.stopPropagation(); if (e.key === "Tab" || e.key === "Enter") { - // console.log(this._recording); - // if (this._editorView) { - // const state = this._editorView.state; - // const now = Date.now(); - // let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(now / 1000) }); - // if (!this._break && state.selection.to !== state.selection.from) { - // for (let i = state.selection.from; i <= state.selection.to; i++) { - // const pos = state.doc.resolve(i); - // const um = Array.from(pos.marks()).find(m => m.type === schema.marks.user_mark); - // if (um) { - // mark = um; - // break; - // } - // } - // } - // const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime(); - // this._break = false; - // let value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000; - // //let value = "[0:02]"; - // const from = state.selection.from; - // const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); - - // this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1))); - // } + if (e.key === "Enter" && this.layoutDoc._timeStampOnEnter) { + this.insertTime(); + } e.preventDefault(); } if (e.key === " " || this._lastTimedMark?.attrs.userid !== Doc.CurrentUserEmail) { @@ -1371,6 +1440,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } render() { TraceMobx(); + trace(); + // if (this.props.Document.recordingStart) { + // console.log(DateCast(this.props.Document.recordingStart).date.getTime()); + // } + const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; -- cgit v1.2.3-70-g09d2 From b827bdfecc5646b479c7e5654ed98243de91cf9a Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Thu, 6 Aug 2020 17:24:56 -0700 Subject: cleaned up code and fixed bugs --- src/client/views/nodes/AudioBox.tsx | 415 ++++++--------------- src/client/views/nodes/AudioResizer.scss | 11 - src/client/views/nodes/AudioResizer.tsx | 48 --- .../views/nodes/formattedText/FormattedTextBox.tsx | 18 +- 4 files changed, 114 insertions(+), 378 deletions(-) delete mode 100644 src/client/views/nodes/AudioResizer.scss delete mode 100644 src/client/views/nodes/AudioResizer.tsx (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 1d060120e..11dfe5fe6 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -60,7 +60,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _first: boolean = false; _dragging = false; @@ -77,7 +76,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; @@ -126,36 +124,38 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + // for determining if the link is created after recording (since it will use linkTime rather than creation date) + DocListCast(this.dataDoc.links).map((l, i) => { let la1 = l.anchor1 as Doc; let la2 = l.anchor2 as Doc; - let linkTime = NumCast(l.anchor2_timecode); - let endTime; - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - la1 = l.anchor2 as Doc; - la2 = l.anchor1 as Doc; - linkTime = NumCast(l.anchor1_timecode); - } - if (la2.audioStart) { - linkTime = NumCast(la2.audioStart); - } + if (la1 === sel || la2 === sel) { // if the selected document is linked to this audio + let linkTime = NumCast(l.anchor2_timecode); + let endTime; + if (Doc.AreProtosEqual(la1, this.dataDoc)) { + la1 = l.anchor2 as Doc; + la2 = l.anchor1 as Doc; + linkTime = NumCast(l.anchor1_timecode); + } + if (la2.audioStart) { + linkTime = NumCast(la2.audioStart); + } - if (la1.audioStart) { - linkTime = NumCast(la1.audioStart); - } + if (la1.audioStart) { + linkTime = NumCast(la1.audioStart); + } - if (la1.audioEnd) { - endTime = NumCast(la1.audioEnd); - } + if (la1.audioEnd) { + endTime = NumCast(la1.audioEnd); + } - if (la2.audioEnd) { - endTime = NumCast(la2.audioEnd); - } + if (la2.audioEnd) { + endTime = NumCast(la2.audioEnd); + } - if (linkTime) { - link = true; - this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime); + if (linkTime) { + link = true; + this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && (endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime)); + } } }); } @@ -189,19 +189,19 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - if (this._repeat) { - this.playFrom(0); - } else { - this._ele!.pause(); - this.audioState = "paused"; - } + console.log("pause"); + this._ele!.pause(); + this.audioState = "paused"; }); + // play audio for documents created during recording playFromTime = (absoluteTime: number) => { this.recordingStart && this.playFrom((absoluteTime - this.recordingStart) / 1000); } + // play back the audio from time @action playFrom = (seekTimeInSeconds: number, endTime: number = this.dataDoc.duration) => { let play; @@ -220,15 +220,15 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.audioState = "playing"); if (endTime !== this.dataDoc.duration) { - play = setTimeout(() => this.pause(), (this._duration) * 1000); + play = setTimeout(() => this.pause(), (this._duration) * 1000); // use setTimeout to play a specific duration } - } else { // this is getting called because time is greater than duration + } else { this.pause(); } } } - + // update the recording time updateRecordTime = () => { if (this.audioState === "recording") { if (this._paused) { @@ -241,6 +241,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { this._stream = await navigator.mediaDevices.getUserMedia({ audio: true }); this._recorder = new MediaRecorder(this._stream); @@ -259,6 +260,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this._recorder && this.stopRecording(), 60 * 60 * 1000); // stop after an hour } + // context menu specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when link is selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" }); @@ -268,6 +270,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { this._recorder.stop(); this._recorder = undefined; @@ -278,6 +281,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { this._recorder ? this.stopRecording() : this.recordAudioAnnotation(); @@ -285,14 +289,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent { this.playFrom(this._ele!.paused ? this._ele!.currentTime : -1); e.stopPropagation(); } - onStop = (e: any) => { - this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect; - e.stopPropagation(); - } + + // creates a text document for dictation onFile = (e: any) => { const newDoc = Docs.Create.TextDocument("", { title: "", _chromeStatus: "disabled", @@ -306,125 +309,21 @@ export class AudioBox extends ViewBoxAnnotatableComponent { e?.addEventListener("timeupdate", this.timecodeChanged); e?.addEventListener("ended", this.pause); this._ele = e; } + // returns the path of the audio file @computed get path() { const field = Cast(this.props.Document[this.props.fieldKey], AudioField); const path = (field instanceof AudioField) ? field.url.href : ""; return path === nullAudio ? "" : path; } - // @action - // buckets = () => { - // let audioCtx = new (window.AudioContext)(); - // const buckets: number[] = []; - - // axios({ url: this.path, responseType: "arraybuffer" }) - // .then(response => runInAction(() => { - // let audioData = response.data; - - // audioCtx.decodeAudioData(audioData, buffer => { - // let decodedAudioData = buffer.getChannelData(0); - // const NUMBER_OF_BUCKETS = 100; - // let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); - - // for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { - // let startingPoint = i * bucketDataSize; - // let endingPoint = i * bucketDataSize + bucketDataSize; - // let max = 0; - // for (let j = startingPoint; j < endingPoint; j++) { - // if (decodedAudioData[j] > max) { - // max = decodedAudioData[j]; - // } - // } - // let size = Math.abs(max); - // buckets.push(size / 2); - // } - - // }); - // return buckets - // })); - // } - - @action - buckets = async () => { - let audioCtx = new (window.AudioContext)(); - const buckets: number[] = []; - - axios({ url: this.path, responseType: "arraybuffer" }) - .then(response => { - let audioData = response.data; - - audioCtx.decodeAudioData(audioData, action(buffer => { - let decodedAudioData = buffer.getChannelData(0); - const NUMBER_OF_BUCKETS = 100; - let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); - - for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { - let startingPoint = i * bucketDataSize; - let endingPoint = i * bucketDataSize + bucketDataSize; - let max = 0; - for (let j = startingPoint; j < endingPoint; j++) { - if (decodedAudioData[j] > max) { - max = decodedAudioData[j]; - } - } - let size = Math.abs(max); - buckets.push(size / 2); - this._buckets.push(size / 2); - } - - })); - return buckets; - }); - } - - @computed get peaks() { - // let audioCtx = new (window.AudioContext)(); - // let buckets: number[] = []; - - // return (async () => { - // await axios({ url: this.path, responseType: "arraybuffer" }) - // .then(response => { - // let audioData = response.data; - - // audioCtx.decodeAudioData(audioData, buffer => { - // let decodedAudioData = buffer.getChannelData(0); - // const NUMBER_OF_BUCKETS = 100; - // let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); - - - - // for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { - // let startingPoint = i * bucketDataSize; - // let endingPoint = i * bucketDataSize + bucketDataSize; - // let max = 0; - // for (let j = startingPoint; j < endingPoint; j++) { - // if (decodedAudioData[j] > max) { - // max = decodedAudioData[j]; - // } - // } - // let size = Math.abs(max); - // console.log(size); - // buckets.push(size / 2); - // console.log(buckets); - // } - // }); - // console.log(buckets); - // return buckets; - // }); - // console.log(buckets.length); - // return buckets; - // })(); - - - return this.buckets(); - } - + // returns the html audio element @computed get audio() { const interactive = this.active() ? "-interactive" : ""; return