aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/FormattedTextBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/FormattedTextBox.tsx')
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx85
1 files changed, 58 insertions, 27 deletions
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 8f4cefbf4..f18183600 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -20,7 +20,7 @@ import { InkTool } from '../../../new_fields/InkField';
import { RichTextField } from "../../../new_fields/RichTextField";
import { RichTextUtils } from '../../../new_fields/RichTextUtils';
import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { TraceMobx } from '../../../new_fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, Utils } from '../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/GoogleApiClientUtils';
@@ -82,6 +82,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
private _lastY = 0;
private _undoTyping?: UndoManager.Batch;
private _searchReactionDisposer?: Lambda;
+ private _recordReactionDisposer: Opt<IReactionDisposer>;
private _scrollToRegionReactionDisposer: Opt<IReactionDisposer>;
private _reactionDisposer: Opt<IReactionDisposer>;
private _heightReactionDisposer: Opt<IReactionDisposer>;
@@ -92,6 +93,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
private _scrollDisposer: Opt<IReactionDisposer>;
private dropDisposer?: DragManager.DragDropDisposer;
+ @computed get _recording() { return this.dataDoc.audioState === "recording"; }
+ set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; }
+
@observable private _entered = false;
public static FocusedBox: FormattedTextBox | undefined;
@@ -186,7 +190,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
(tx.storedMarks && !this._editorView.state.storedMarks) && (this._editorView.state.storedMarks = tx.storedMarks);
const tsel = this._editorView.state.selection.$from;
- tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 5000 - 1000)));
+ tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 1000)));
const curText = state.doc.textBetween(0, state.doc.content.size, "\n\n");
const curTemp = Cast(this.props.Document[this.props.fieldKey + "-textTemplate"], RichTextField);
if (!this._applyingChange) {
@@ -387,7 +391,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
!this.props.Document.expandedTemplate && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = true; Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); }, icon: "eye" });
funcs.push({ description: "Toggle Single Line", event: () => this.props.Document._singleLine = !this.props.Document._singleLine, icon: "expand-arrows-alt" });
funcs.push({ description: "Toggle Sidebar", event: () => this.props.Document._showSidebar = !this.props.Document._showSidebar, icon: "expand-arrows-alt" });
- funcs.push({ description: "Record Bullet", event: () => this.recordBullet(), icon: "expand-arrows-alt" });
+ funcs.push({ description: "Toggle Audio", event: () => this.props.Document._showAudio = !this.props.Document._showAudio, icon: "expand-arrows-alt" });
funcs.push({ description: "Toggle Menubar", event: () => this.toggleMenubar(), icon: "expand-arrows-alt" });
["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option =>
funcs.push({
@@ -405,12 +409,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: funcs, icon: "asterisk" });
}
- @observable _recording = false;
-
recordDictation = () => {
- //this._editorView!.focus();
- if (this._recording) return;
- runInAction(() => this._recording = true);
DictationManager.Controls.listen({
interimHandler: this.setCurrentBulletContent,
continuous: { indefinite: false },
@@ -418,13 +417,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
if (results && [DictationManager.Controls.Infringed].includes(results)) {
DictationManager.Controls.stop();
}
- this._editorView!.focus();
+ //this._editorView!.focus();
});
}
- stopDictation = (abort: boolean) => {
- runInAction(() => this._recording = false);
- DictationManager.Controls.stop(!abort);
- }
+ stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); }
@action
toggleMenubar = () => {
@@ -449,12 +445,28 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
setCurrentBulletContent = (value: string) => {
if (this._editorView) {
let state = this._editorView.state;
+ let now = Date.now();
+ if (NumCast(this.props.Document.recordingStart, -1) === 0) {
+ this.props.Document.recordingStart = now = AudioBox.START;
+ }
+ console.log("NOW = " + (now - AudioBox.START) / 1000);
+ 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;
+ }
+ }
+ }
+ this._break = false;
+ console.log("start = " + (mark.attrs.modified * 1000 - AudioBox.START) / 1000);
+ value = "" + (mark.attrs.modified * 1000 - AudioBox.START) / 1000 + value;
const from = state.selection.from;
- const to = state.selection.to;
- this._editorView.dispatch(state.tr.insertText(value, from, to));
- state = this._editorView.state;
- const updated = TextSelection.create(state.doc, from, from + value.length);
- this._editorView.dispatch(state.tr.setSelection(updated));
+ 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)));
}
}
@@ -558,6 +570,17 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
search => search ? this.highlightSearchTerms([Doc.SearchQuery()]) : this.unhighlightSearchTerms(),
{ fireImmediately: true });
+ this._recordReactionDisposer = reaction(() => this._recording,
+ () => {
+ if (this._recording) {
+ setTimeout(action(() => {
+ this.stopDictation(true);
+ setTimeout(() => this.recordDictation(), 500);
+ }), 500);
+ } else setTimeout(() => this.stopDictation(true), 0);
+ }
+ );
+
this._scrollToRegionReactionDisposer = reaction(
() => StrCast(this.layoutDoc.scrollToLinkID),
async (scrollToLinkID) => {
@@ -807,7 +830,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
}
(selectOnLoad /* || !rtfField?.Text*/) && this._editorView!.focus();
// add user mark for any first character that was typed since the user mark that gets set in KeyPress won't have been called yet.
- this._editorView!.state.storedMarks = [...(this._editorView!.state.storedMarks ? this._editorView!.state.storedMarks : []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) })];
+ this._editorView!.state.storedMarks = [...(this._editorView!.state.storedMarks ? this._editorView!.state.storedMarks : []), schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })];
}
getFont(font: string) {
switch (font) {
@@ -831,6 +854,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
this._pullReactionDisposer?.();
this._heightReactionDisposer?.();
this._searchReactionDisposer?.();
+ this._recordReactionDisposer?.();
this._buttonBarReactionDisposer?.();
this._editorView?.destroy();
}
@@ -838,7 +862,19 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
static _downEvent: any;
_downX = 0;
_downY = 0;
+ _break = false;
onPointerDown = (e: React.PointerEvent): void => {
+ if (this._recording && !e.ctrlKey && e.button === 0) {
+ this.stopDictation(true);
+ this._break = true;
+ let state = this._editorView!.state;
+ const to = state.selection.to;
+ const updated = TextSelection.create(state.doc, to, to);
+ this._editorView!.dispatch(this._editorView!.state.tr.setSelection(updated).insertText("\n", to));
+ e.preventDefault();
+ e.stopPropagation();
+ if (this._recording) setTimeout(() => this.recordDictation(), 500);
+ }
this._downX = e.clientX;
this._downY = e.clientY;
this.doLinkOnDeselect();
@@ -955,7 +991,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
this.props.select(e.ctrlKey);
this.hitBulletTargets(e.clientX, e.clientY, e.shiftKey, false);
}
- if (this._recording) setTimeout(() => { this.stopDictation(true); setTimeout(() => this.recordDictation(), 500); }, 500);
}
// this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them.
@@ -1062,17 +1097,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
if (e.key === "Tab" || e.key === "Enter") {
e.preventDefault();
}
- const mark = e.key !== " " && this._lastTimedMark ? this._lastTimedMark : schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) });
+ const mark = e.key !== " " && this._lastTimedMark ? this._lastTimedMark : schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) });
this._lastTimedMark = mark;
this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark));
if (!this._undoTyping) {
this._undoTyping = UndoManager.StartBatch("undoTyping");
}
- if (this._recording) {
- this.stopDictation(true);
- setTimeout(() => this.recordDictation(), 250);
- }
}
onscrolled = (ev: React.UIEvent) => {
@@ -1169,8 +1200,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
</div>}
{!this.props.Document._showAudio ? (null) :
<div className="formattedTextBox-dictation"
- onClick={e => {
- this._recording ? this.stopDictation(true) : this.recordDictation();
+ onPointerDown={e => {
+ runInAction(() => this._recording = !this._recording);
setTimeout(() => this._editorView!.focus(), 500);
e.stopPropagation();
}} >