aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DictationManager.ts78
-rw-r--r--src/client/util/DocumentManager.ts4
-rw-r--r--src/client/util/DragManager.ts37
-rw-r--r--src/client/util/RichTextSchema.tsx2
-rw-r--r--src/client/util/SelectionManager.ts1
5 files changed, 89 insertions, 33 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 9c61fe125..fb3c15cea 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -2,9 +2,10 @@ import { SelectionManager } from "./SelectionManager";
import { DocumentView } from "../views/nodes/DocumentView";
import { UndoManager } from "./UndoManager";
import * as interpreter from "words-to-numbers";
+import { DocumentType } from "../documents/DocumentTypes";
import { Doc } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
-import { Docs, DocumentType } from "../documents/Documents";
+import { Docs } from "../documents/Documents";
import { CollectionViewType } from "../views/collections/CollectionBaseView";
import { Cast, CastCtor } from "../../new_fields/Types";
import { listSpec } from "../../new_fields/Schema";
@@ -12,6 +13,7 @@ import { AudioField, ImageField } from "../../new_fields/URLField";
import { HistogramField } from "../northstar/dash-fields/HistogramField";
import { MainView } from "../views/MainView";
import { Utils } from "../../Utils";
+import { RichTextField } from "../../new_fields/RichTextField";
/**
* This namespace provides a singleton instance of a manager that
@@ -43,7 +45,7 @@ export namespace DictationManager {
export namespace Controls {
- const infringe = "unable to process: dictation manager still involved in previous session";
+ export const Infringed = "unable to process: dictation manager still involved in previous session";
const intraSession = ". ";
const interSession = " ... ";
@@ -62,35 +64,45 @@ export namespace DictationManager {
export type ListeningUIStatus = { interim: boolean } | false;
export interface ListeningOptions {
+ useOverlay: boolean;
language: string;
continuous: ContinuityArgs;
delimiters: DelimiterArgs;
interimHandler: InterimResultHandler;
tryExecute: boolean;
+ terminators: string[];
}
export const listen = async (options?: Partial<ListeningOptions>) => {
let results: string | undefined;
let main = MainView.Instance;
- main.dictationOverlayVisible = true;
- main.isListening = { interim: false };
+ let overlay = options !== undefined && options.useOverlay;
+ if (overlay) {
+ main.dictationOverlayVisible = true;
+ main.isListening = { interim: false };
+ }
try {
results = await listenImpl(options);
if (results) {
Utils.CopyText(results);
- main.isListening = false;
- let execute = options && options.tryExecute;
- main.dictatedPhrase = execute ? results.toLowerCase() : results;
- main.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
+ if (overlay) {
+ main.isListening = false;
+ let execute = options && options.tryExecute;
+ main.dictatedPhrase = execute ? results.toLowerCase() : results;
+ main.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
+ }
+ options && options.tryExecute && await DictationManager.Commands.execute(results);
}
} catch (e) {
- main.isListening = false;
- main.dictatedPhrase = results = `dictation error: ${"error" in e ? e.error : "unknown error"}`;
- main.dictationSuccess = false;
+ if (overlay) {
+ main.isListening = false;
+ main.dictatedPhrase = results = `dictation error: ${"error" in e ? e.error : "unknown error"}`;
+ main.dictationSuccess = false;
+ }
} finally {
- main.initiateDictationFade();
+ overlay && main.initiateDictationFade();
}
return results;
@@ -98,7 +110,7 @@ export namespace DictationManager {
const listenImpl = (options?: Partial<ListeningOptions>) => {
if (isListening) {
- return infringe;
+ return Infringed;
}
isListening = true;
@@ -126,6 +138,12 @@ export namespace DictationManager {
recognizer.onresult = (e: SpeechRecognitionEvent) => {
current = synthesize(e, intra);
+ let matchedTerminator: string | undefined;
+ if (options && options.terminators && (matchedTerminator = options.terminators.find(end => current ? current.trim().toLowerCase().endsWith(end.toLowerCase()) : false))) {
+ current = matchedTerminator;
+ recognizer.abort();
+ return complete();
+ }
handler && handler(current);
isManuallyStopped && complete();
};
@@ -161,13 +179,13 @@ export namespace DictationManager {
}
isManuallyStopped = true;
salvageSession ? recognizer.stop() : recognizer.abort();
- let main = MainView.Instance;
- if (main.dictationOverlayVisible) {
- main.cancelDictationFade();
- main.dictationOverlayVisible = false;
- main.dictationSuccess = undefined;
- setTimeout(() => main.dictatedPhrase = placeholder, 500);
- }
+ // let main = MainView.Instance;
+ // if (main.dictationOverlayVisible) {
+ // main.cancelDictationFade();
+ // main.dictationOverlayVisible = false;
+ // main.dictationSuccess = undefined;
+ // setTimeout(() => main.dictatedPhrase = placeholder, 500);
+ // }
};
const synthesize = (e: SpeechRecognitionEvent, delimiter?: string) => {
@@ -299,11 +317,20 @@ export namespace DictationManager {
}
}],
- ["promote", {
+ ["new outline", {
action: (target: DocumentView) => {
- console.log(target);
- },
- restrictTo: [DocumentType.TEXT]
+ let newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" });
+ newBox.autoHeight = true;
+ let proto = newBox.proto!;
+ proto.page = -1;
+ let prompt = "Press alt + r to start dictating here...";
+ let head = 3;
+ let anchor = head + prompt.length;
+ let proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`;
+ proto.data = new RichTextField(proseMirrorState);
+ proto.backgroundColor = "#eeffff";
+ target.props.addDocTab(newBox, proto, "onRight");
+ }
}]
]);
@@ -317,6 +344,9 @@ export namespace DictationManager {
let what = matches[2];
let dataDoc = Doc.GetProto(target.props.Document);
let fieldKey = "data";
+ if (isNaN(count)) {
+ return;
+ }
for (let i = 0; i < count; i++) {
let created: Doc | undefined;
switch (what) {
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 7f526b247..124faf266 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -9,6 +9,7 @@ import { CollectionView } from '../views/collections/CollectionView';
import { DocumentView } from '../views/nodes/DocumentView';
import { LinkManager } from './LinkManager';
import { undoBatch, UndoManager } from './UndoManager';
+import { Scripting } from './Scripting';
export class DocumentManager {
@@ -202,4 +203,5 @@ export class DocumentManager {
return 1;
}
}
-} \ No newline at end of file
+}
+Scripting.addGlobal(function focus(doc: any) { DocumentManager.Instance.getDocumentViews(Doc.GetProto(doc)).map(view => view.props.focus(doc, true)) }) \ No newline at end of file
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 0b6d9b5e5..748fb9d13 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,5 +1,5 @@
import { action, runInAction } from "mobx";
-import { Doc } from "../../new_fields/Doc";
+import { Doc, Field } from "../../new_fields/Doc";
import { Cast, StrCast } from "../../new_fields/Types";
import { URLField } from "../../new_fields/URLField";
import { emptyFunction } from "../../Utils";
@@ -9,8 +9,11 @@ import { DocumentManager } from "./DocumentManager";
import { LinkManager } from "./LinkManager";
import { SelectionManager } from "./SelectionManager";
import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
-import { DocumentDecorations } from "../views/DocumentDecorations";
-import { NumberLiteralType } from "typescript";
+import { Docs } from "../documents/Documents";
+import { CompileScript } from "./Scripting";
+import { ScriptField } from "../../new_fields/ScriptField";
+import { List } from "../../new_fields/List";
+import { PrefetchProxy } from "../../new_fields/Proxy";
export type dropActionType = "alias" | "copy" | undefined;
export function SetupDrag(
@@ -142,6 +145,8 @@ export namespace DragManager {
withoutShiftDrag?: boolean;
+ finishDrag?: (dropData: { [id: string]: any }) => void;
+
offsetX?: number;
offsetY?: number;
@@ -211,6 +216,7 @@ export namespace DragManager {
dropAction: dropActionType;
userDropAction: dropActionType;
moveDocument?: MoveFunction;
+ applyAsTemplate?: boolean;
[id: string]: any;
}
@@ -235,7 +241,7 @@ export namespace DragManager {
export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
runInAction(() => StartDragFunctions.map(func => func()));
- StartDrag(eles, dragData, downX, downY, options,
+ StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
(dropData: { [id: string]: any }) => {
(dropData.droppedDocuments = dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ?
dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) :
@@ -246,6 +252,27 @@ export namespace DragManager {
});
}
+ export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], downX: number, downY: number, options?: DragOptions) {
+ let dragData = new DragManager.DocumentDragData([], [undefined]);
+ runInAction(() => StartDragFunctions.map(func => func()));
+ StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
+ (dropData: { [id: string]: any }) => {
+ let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+ let compiled = CompileScript(script, {
+ params: { doc: Doc.name },
+ typecheck: false,
+ editable: true
+ });
+ if (compiled.compiled) {
+ let scriptField = new ScriptField(compiled);
+ bd.onClick = scriptField;
+ }
+ params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+ bd.buttonParams = new List<string>(params);
+ dropData.droppedDocuments = [bd];
+ });
+ }
+
export function StartLinkedDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
dragData.moveDocument = moveLinkedDocument;
@@ -481,7 +508,7 @@ export namespace DragManager {
// if (parent && dragEle) parent.appendChild(dragEle);
});
if (target) {
- if (finishDrag) finishDrag(dragData);
+ finishDrag && finishDrag(dragData);
target.dispatchEvent(
new CustomEvent<DropEvent>("dashOnDrop", {
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 6d2abfaa2..9fdda4845 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -105,7 +105,6 @@ export const nodes: { [index: string]: NodeSpec } = {
// }
// }]
},
-
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
// `alt`, and `href` attributes. The latter two default to the empty
// string.
@@ -197,7 +196,6 @@ export const nodes: { [index: string]: NodeSpec } = {
...listItem,
content: 'paragraph block*'
},
-
};
const emDOM: DOMOutputSpecArray = ["em", 0];
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index ee623d082..9efef888d 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -4,7 +4,6 @@ import { DocumentView } from "../views/nodes/DocumentView";
import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
import { NumCast, StrCast } from "../../new_fields/Types";
import { InkingControl } from "../views/InkingControl";
-import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
export namespace SelectionManager {