aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/DictationManager.ts
diff options
context:
space:
mode:
authorandrewdkim <adkim414@gmail.com>2019-11-12 17:30:02 -0500
committerandrewdkim <adkim414@gmail.com>2019-11-12 17:30:02 -0500
commitfb3a8258298589b911c73c18fdb086c8815e27c8 (patch)
treec97973e8cc2d828b9ce7486b421fdcf2985c49e2 /src/client/util/DictationManager.ts
parent4d4db3aecf54a501a981c239feacdfddfe71152c (diff)
parentecbe527575bab2cb5f1ced278039ec0a6fc50809 (diff)
merge from master
Diffstat (limited to 'src/client/util/DictationManager.ts')
-rw-r--r--src/client/util/DictationManager.ts73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index c4016d2a5..6bbd3d0ed 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -3,10 +3,10 @@ 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 { Doc, Opt } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
import { Docs } from "../documents/Documents";
-import { CollectionViewType } from "../views/collections/CollectionBaseView";
+import { CollectionViewType } from "../views/collections/CollectionView";
import { Cast, CastCtor } from "../../new_fields/Types";
import { listSpec } from "../../new_fields/Schema";
import { AudioField, ImageField } from "../../new_fields/URLField";
@@ -14,6 +14,7 @@ import { HistogramField } from "../northstar/dash-fields/HistogramField";
import { MainView } from "../views/MainView";
import { Utils } from "../../Utils";
import { RichTextField } from "../../new_fields/RichTextField";
+import { DictationOverlay } from "../views/DictationOverlay";
/**
* This namespace provides a singleton instance of a manager that
@@ -40,23 +41,36 @@ export namespace DictationManager {
webkitSpeechRecognition: any;
}
}
- const { webkitSpeechRecognition }: CORE.IWindow = window as CORE.IWindow;
+ const { webkitSpeechRecognition }: CORE.IWindow = window as any as CORE.IWindow;
export const placeholder = "Listening...";
export namespace Controls {
export const Infringed = "unable to process: dictation manager still involved in previous session";
+ const browser = (() => {
+ let identifier = navigator.userAgent.toLowerCase();
+ if (identifier.indexOf("safari") >= 0) {
+ return "Safari";
+ }
+ if (identifier.indexOf("chrome") >= 0) {
+ return "Chrome";
+ }
+ if (identifier.indexOf("firefox") >= 0) {
+ return "Firefox";
+ }
+ return "Unidentified Browser";
+ })();
+ const unsupported = `listening is not supported in ${browser}`;
const intraSession = ". ";
const interSession = " ... ";
- let isListening = false;
+ export let isListening = false;
let isManuallyStopped = false;
let current: string | undefined = undefined;
let sessionResults: string[] = [];
- const recognizer: SpeechRecognition = new webkitSpeechRecognition() || new SpeechRecognition();
- recognizer.onstart = () => console.log("initiating speech recognition session...");
+ const recognizer: Opt<SpeechRecognition> = webkitSpeechRecognition ? new webkitSpeechRecognition() : undefined;
export type InterimResultHandler = (results: string) => any;
export type ContinuityArgs = { indefinite: boolean } | false;
@@ -75,12 +89,11 @@ export namespace DictationManager {
export const listen = async (options?: Partial<ListeningOptions>) => {
let results: string | undefined;
- let main = MainView.Instance;
let overlay = options !== undefined && options.useOverlay;
if (overlay) {
- main.dictationOverlayVisible = true;
- main.isListening = { interim: false };
+ DictationOverlay.Instance.dictationOverlayVisible = true;
+ DictationOverlay.Instance.isListening = { interim: false };
}
try {
@@ -88,27 +101,31 @@ export namespace DictationManager {
if (results) {
Utils.CopyText(results);
if (overlay) {
- main.isListening = false;
+ DictationOverlay.Instance.isListening = false;
let execute = options && options.tryExecute;
- main.dictatedPhrase = execute ? results.toLowerCase() : results;
- main.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
+ DictationOverlay.Instance.dictatedPhrase = execute ? results.toLowerCase() : results;
+ DictationOverlay.Instance.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
}
options && options.tryExecute && await DictationManager.Commands.execute(results);
}
} catch (e) {
if (overlay) {
- main.isListening = false;
- main.dictatedPhrase = results = `dictation error: ${"error" in e ? e.error : "unknown error"}`;
- main.dictationSuccess = false;
+ DictationOverlay.Instance.isListening = false;
+ DictationOverlay.Instance.dictatedPhrase = results = `dictation error: ${"error" in e ? e.error : "unknown error"}`;
+ DictationOverlay.Instance.dictationSuccess = false;
}
} finally {
- overlay && main.initiateDictationFade();
+ overlay && DictationOverlay.Instance.initiateDictationFade();
}
return results;
};
const listenImpl = (options?: Partial<ListeningOptions>) => {
+ if (!recognizer) {
+ console.log(unsupported);
+ return unsupported;
+ }
if (isListening) {
return Infringed;
}
@@ -121,6 +138,7 @@ export namespace DictationManager {
let intra = options && options.delimiters ? options.delimiters.intra : undefined;
let inter = options && options.delimiters ? options.delimiters.inter : undefined;
+ recognizer.onstart = () => console.log("initiating speech recognition session...");
recognizer.interimResults = handler !== undefined;
recognizer.continuous = continuous === undefined ? false : continuous !== false;
recognizer.lang = language === undefined ? "en-US" : language;
@@ -128,7 +146,6 @@ export namespace DictationManager {
recognizer.start();
return new Promise<string>((resolve, reject) => {
-
recognizer.onerror = (e: SpeechRecognitionError) => {
if (!(indefinite && e.error === "no-speech")) {
recognizer.stop();
@@ -167,16 +184,23 @@ export namespace DictationManager {
} else {
resolve(current);
}
- reset();
+ current = undefined;
+ sessionResults = [];
+ isListening = false;
+ isManuallyStopped = false;
+ recognizer.onresult = null;
+ recognizer.onerror = null;
+ recognizer.onend = null;
};
});
};
export const stop = (salvageSession = true) => {
- if (!isListening) {
+ if (!isListening || !recognizer) {
return;
}
+ isListening = false;
isManuallyStopped = true;
salvageSession ? recognizer.stop() : recognizer.abort();
// let main = MainView.Instance;
@@ -197,16 +221,6 @@ export namespace DictationManager {
return transcripts.join(delimiter || intraSession);
};
- const reset = () => {
- current = undefined;
- sessionResults = [];
- isListening = false;
- isManuallyStopped = false;
- recognizer.onresult = null;
- recognizer.onerror = null;
- recognizer.onend = null;
- };
-
}
export namespace Commands {
@@ -322,7 +336,6 @@ export namespace DictationManager {
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;