aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/DictationManager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/DictationManager.ts')
-rw-r--r--src/client/util/DictationManager.ts353
1 files changed, 178 insertions, 175 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index a93b2f573..a6dcda4bc 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -1,4 +1,6 @@
import * as interpreter from "words-to-numbers";
+// @ts-ignore bcz: how are you supposed to include these definitions since dom-speech-recognition isn't a module?
+import type { } from "@types/dom-speech-recognition";
import { Doc, Opt } from "../../fields/Doc";
import { List } from "../../fields/List";
import { RichTextField } from "../../fields/RichTextField";
@@ -13,6 +15,7 @@ import { DocumentView } from "../views/nodes/DocumentView";
import { SelectionManager } from "./SelectionManager";
import { UndoManager } from "./UndoManager";
+
/**
* This namespace provides a singleton instance of a manager that
* handles the listening and text-conversion of user speech.
@@ -102,17 +105,17 @@ export namespace DictationManager {
try {
results = await (pendingListen = listenImpl(options));
pendingListen = undefined;
- if (results) {
- Utils.CopyText(results);
- if (overlay) {
- DictationOverlay.Instance.isListening = false;
- const execute = options?.tryExecute;
- DictationOverlay.Instance.dictatedPhrase = execute ? results.toLowerCase() : results;
- DictationOverlay.Instance.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
- }
- options?.tryExecute && await DictationManager.Commands.execute(results);
- }
- } catch (e) {
+ // if (results) {
+ // Utils.CopyText(results);
+ // if (overlay) {
+ // DictationOverlay.Instance.isListening = false;
+ // const execute = options?.tryExecute;
+ // DictationOverlay.Instance.dictatedPhrase = execute ? results.toLowerCase() : results;
+ // DictationOverlay.Instance.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
+ // }
+ // options?.tryExecute && await DictationManager.Commands.execute(results);
+ // }
+ } catch (e: any) {
console.log(e);
if (overlay) {
DictationOverlay.Instance.isListening = false;
@@ -188,7 +191,7 @@ export namespace DictationManager {
current && sessionResults.push(current);
sessionResults.length && resolve(sessionResults.join(inter || interSession));
} else {
- resolve(current);
+ resolve(current || "");
}
current = undefined;
sessionResults = [];
@@ -222,168 +225,168 @@ export namespace DictationManager {
}
- export namespace Commands {
-
- export const dictationFadeDuration = 2000;
-
- export type IndependentAction = (target: DocumentView) => any | Promise<any>;
- export type IndependentEntry = { action: IndependentAction, restrictTo?: DocumentType[] };
-
- export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => any | Promise<any>;
- export type DependentEntry = { expression: RegExp, action: DependentAction, restrictTo?: DocumentType[] };
-
- export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value);
- export const RegisterDependent = (entry: DependentEntry) => Dependent.push(entry);
-
- export const execute = async (phrase: string) => {
- return UndoManager.RunInBatch(async () => {
- const targets = SelectionManager.Views();
- if (!targets || !targets.length) {
- return;
- }
-
- phrase = phrase.toLowerCase();
- const entry = Independent.get(phrase);
-
- if (entry) {
- let success = false;
- const restrictTo = entry.restrictTo;
- for (const target of targets) {
- if (!restrictTo || validate(target, restrictTo)) {
- await entry.action(target);
- success = true;
- }
- }
- return success;
- }
-
- for (const entry of Dependent) {
- const regex = entry.expression;
- const matches = regex.exec(phrase);
- regex.lastIndex = 0;
- if (matches !== null) {
- let success = false;
- const restrictTo = entry.restrictTo;
- for (const target of targets) {
- if (!restrictTo || validate(target, restrictTo)) {
- await entry.action(target, matches);
- success = true;
- }
- }
- return success;
- }
- }
-
- return false;
- }, "Execute Command");
- };
-
- const ConstructorMap = new Map<DocumentType, CastCtor>([
- [DocumentType.COL, listSpec(Doc)],
- [DocumentType.AUDIO, AudioField],
- [DocumentType.IMG, ImageField],
- [DocumentType.IMPORT, listSpec(Doc)],
- [DocumentType.RTF, "string"]
- ]);
-
- const tryCast = (view: DocumentView, type: DocumentType) => {
- const ctor = ConstructorMap.get(type);
- if (!ctor) {
- return false;
- }
- return Cast(Doc.GetProto(view.props.Document).data, ctor) !== undefined;
- };
-
- const validate = (target: DocumentView, types: DocumentType[]) => {
- for (const type of types) {
- if (tryCast(target, type)) {
- return true;
- }
- }
- return false;
- };
-
- const interpretNumber = (number: string) => {
- const initial = parseInt(number);
- if (!isNaN(initial)) {
- return initial;
- }
- const converted = interpreter.wordsToNumbers(number, { fuzzy: true });
- if (converted === null) {
- return NaN;
- }
- return typeof converted === "string" ? parseInt(converted) : converted;
- };
-
- const Independent = new Map<string, IndependentEntry>([
-
- ["clear", {
- action: (target: DocumentView) => Doc.GetProto(target.props.Document).data = new List(),
- restrictTo: [DocumentType.COL]
- }],
-
- ["open fields", {
- action: (target: DocumentView) => {
- const kvp = Docs.Create.KVPDocument(target.props.Document, { _width: 300, _height: 300 });
- target.props.addDocTab(kvp, "add:right");
- }
- }],
-
- ["new outline", {
- action: (target: DocumentView) => {
- const newBox = Docs.Create.TextDocument("", { _width: 400, _height: 200, title: "My Outline", _autoHeight: true });
- const proto = newBox.proto!;
- const prompt = "Press alt + r to start dictating here...";
- const head = 3;
- const anchor = head + prompt.length;
- const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"ordered_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, "add:right");
- }
- }]
-
- ]);
-
- const Dependent = new Array<DependentEntry>(
-
- {
- expression: /create (\w+) documents of type (image|nested collection)/g,
- action: (target: DocumentView, matches: RegExpExecArray) => {
- const count = interpretNumber(matches[1]);
- const what = matches[2];
- const dataDoc = Doc.GetProto(target.props.Document);
- const fieldKey = "data";
- if (isNaN(count)) {
- return;
- }
- for (let i = 0; i < count; i++) {
- let created: Doc | undefined;
- switch (what) {
- case "image":
- created = Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg");
- break;
- case "nested collection":
- created = Docs.Create.FreeformDocument([], {});
- break;
- }
- created && Doc.AddDocToList(dataDoc, fieldKey, created);
- }
- },
- restrictTo: [DocumentType.COL]
- },
-
- {
- expression: /view as (freeform|stacking|masonry|schema|tree)/g,
- action: (target: DocumentView, matches: RegExpExecArray) => {
- const mode = matches[1];
- mode && (target.props.Document._viewType = mode);
- },
- restrictTo: [DocumentType.COL]
- }
-
- );
-
- }
+ // export namespace Commands {
+
+ // export const dictationFadeDuration = 2000;
+
+ // export type IndependentAction = (target: DocumentView) => any | Promise<any>;
+ // export type IndependentEntry = { action: IndependentAction, restrictTo?: DocumentType[] };
+
+ // export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => any | Promise<any>;
+ // export type DependentEntry = { expression: RegExp, action: DependentAction, restrictTo?: DocumentType[] };
+
+ // export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value);
+ // export const RegisterDependent = (entry: DependentEntry) => Dependent.push(entry);
+
+ // export const execute = async (phrase: string) => {
+ // return UndoManager.RunInBatch(async () => {
+ // const targets = SelectionManager.Views();
+ // if (!targets || !targets.length) {
+ // return;
+ // }
+
+ // phrase = phrase.toLowerCase();
+ // const entry = Independent.get(phrase);
+
+ // if (entry) {
+ // let success = false;
+ // const restrictTo = entry.restrictTo;
+ // for (const target of targets) {
+ // if (!restrictTo || validate(target, restrictTo)) {
+ // await entry.action(target);
+ // success = true;
+ // }
+ // }
+ // return success;
+ // }
+
+ // for (const entry of Dependent) {
+ // const regex = entry.expression;
+ // const matches = regex.exec(phrase);
+ // regex.lastIndex = 0;
+ // if (matches !== null) {
+ // let success = false;
+ // const restrictTo = entry.restrictTo;
+ // for (const target of targets) {
+ // if (!restrictTo || validate(target, restrictTo)) {
+ // await entry.action(target, matches);
+ // success = true;
+ // }
+ // }
+ // return success;
+ // }
+ // }
+
+ // return false;
+ // }, "Execute Command");
+ // };
+
+ // const ConstructorMap = new Map<DocumentType, CastCtor>([
+ // [DocumentType.COL, listSpec(Doc)],
+ // [DocumentType.AUDIO, AudioField],
+ // [DocumentType.IMG, ImageField],
+ // [DocumentType.IMPORT, listSpec(Doc)],
+ // [DocumentType.RTF, "string"]
+ // ]);
+
+ // const tryCast = (view: DocumentView, type: DocumentType) => {
+ // const ctor = ConstructorMap.get(type);
+ // if (!ctor) {
+ // return false;
+ // }
+ // return Cast(Doc.GetProto(view.props.Document).data, ctor) !== undefined;
+ // };
+
+ // const validate = (target: DocumentView, types: DocumentType[]) => {
+ // for (const type of types) {
+ // if (tryCast(target, type)) {
+ // return true;
+ // }
+ // }
+ // return false;
+ // };
+
+ // const interpretNumber = (number: string) => {
+ // const initial = parseInt(number);
+ // if (!isNaN(initial)) {
+ // return initial;
+ // }
+ // const converted = interpreter.wordsToNumbers(number, { fuzzy: true });
+ // if (converted === null) {
+ // return NaN;
+ // }
+ // return typeof converted === "string" ? parseInt(converted) : converted;
+ // };
+
+ // const Independent = new Map<string, IndependentEntry>([
+
+ // ["clear", {
+ // action: (target: DocumentView) => Doc.GetProto(target.props.Document).data = new List(),
+ // restrictTo: [DocumentType.COL]
+ // }],
+
+ // ["open fields", {
+ // action: (target: DocumentView) => {
+ // const kvp = Docs.Create.KVPDocument(target.props.Document, { _width: 300, _height: 300 });
+ // target.props.addDocTab(kvp, "add:right");
+ // }
+ // }],
+
+ // ["new outline", {
+ // action: (target: DocumentView) => {
+ // const newBox = Docs.Create.TextDocument("", { _width: 400, _height: 200, title: "My Outline", _autoHeight: true });
+ // const proto = newBox.proto!;
+ // const prompt = "Press alt + r to start dictating here...";
+ // const head = 3;
+ // const anchor = head + prompt.length;
+ // const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"ordered_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, "add:right");
+ // }
+ // }]
+
+ // ]);
+
+ // const Dependent = new Array<DependentEntry>(
+
+ // {
+ // expression: /create (\w+) documents of type (image|nested collection)/g,
+ // action: (target: DocumentView, matches: RegExpExecArray) => {
+ // const count = interpretNumber(matches[1]);
+ // const what = matches[2];
+ // const dataDoc = Doc.GetProto(target.props.Document);
+ // const fieldKey = "data";
+ // if (isNaN(count)) {
+ // return;
+ // }
+ // for (let i = 0; i < count; i++) {
+ // let created: Doc | undefined;
+ // switch (what) {
+ // case "image":
+ // created = Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg");
+ // break;
+ // case "nested collection":
+ // created = Docs.Create.FreeformDocument([], {});
+ // break;
+ // }
+ // created && Doc.AddDocToList(dataDoc, fieldKey, created);
+ // }
+ // },
+ // restrictTo: [DocumentType.COL]
+ // },
+
+ // {
+ // expression: /view as (freeform|stacking|masonry|schema|tree)/g,
+ // action: (target: DocumentView, matches: RegExpExecArray) => {
+ // const mode = matches[1];
+ // mode && (target.props.Document._viewType = mode);
+ // },
+ // restrictTo: [DocumentType.COL]
+ // }
+
+ // );
+
+ // }
} \ No newline at end of file