aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2019-07-31 03:21:59 -0400
committerSam Wilkins <samwilkins333@gmail.com>2019-07-31 03:21:59 -0400
commit8a87f7110b56ca96b3960f6fb3917c7ed8c7a814 (patch)
treede47681ad0ce1e87de6321216bfb20337512a837
parent31a8bb32e696d58816329b66cfc5b92907494d1b (diff)
overlay completed
-rw-r--r--src/client/util/DictationManager.ts12
-rw-r--r--src/client/views/GlobalKeyHandler.ts24
-rw-r--r--src/client/views/Main.scss68
-rw-r--r--src/client/views/MainView.tsx55
4 files changed, 127 insertions, 32 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 6d67f6d6d..80efe12cd 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -1,5 +1,5 @@
import { string } from "prop-types";
-import { observable, action } from "mobx";
+import { observable, action, autorun } from "mobx";
import { SelectionManager } from "./SelectionManager";
import { DocumentView } from "../views/nodes/DocumentView";
import { UndoManager } from "./UndoManager";
@@ -8,6 +8,7 @@ import { Doc } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
import { Docs } from "../documents/Documents";
import { CollectionViewType } from "../views/collections/CollectionBaseView";
+import { MainView } from "../views/MainView";
namespace CORE {
export interface IWindow extends Window {
@@ -22,8 +23,8 @@ export type RegexEntry = { key: RegExp, value: DependentAction };
export default class DictationManager {
public static Instance = new DictationManager();
- private isListening = false;
private recognizer: any;
+ private isListening = false;
constructor() {
this.recognizer = new webkitSpeechRecognition();
@@ -31,18 +32,14 @@ export default class DictationManager {
this.recognizer.continuous = true;
}
- @observable public current = "";
-
- @action
finish = (handler: any, data: any) => {
- this.current = data;
handler(data);
this.stop();
}
stop = () => {
- this.isListening = false;
this.recognizer.stop();
+ this.isListening = false;
}
listen = () => {
@@ -55,7 +52,6 @@ export default class DictationManager {
this.recognizer.onresult = (e: any) => this.finish(resolve, e.results[0][0].transcript);
this.recognizer.onerror = (e: any) => this.finish(reject, e);
});
-
}
private sanitize = (title: string) => {
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 1d3c77ec7..a6020bd3f 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -3,7 +3,7 @@ import { SelectionManager } from "../util/SelectionManager";
import { CollectionDockingView } from "./collections/CollectionDockingView";
import { MainView } from "./MainView";
import { DragManager } from "../util/DragManager";
-import { action } from "mobx";
+import { action, runInAction } from "mobx";
import { Doc } from "../../new_fields/Doc";
import { CognitiveServices } from "../cognitive_services/CognitiveServices";
import DictationManager from "../util/DictationManager";
@@ -74,6 +74,7 @@ export default class KeyManager {
MainView.Instance.toggleColorPicker(true);
SelectionManager.DeselectAll();
DictationManager.Instance.stop();
+ MainView.Instance.dictationOverlayVisible = false;
break;
case "delete":
case "backspace":
@@ -107,11 +108,22 @@ export default class KeyManager {
switch (keyname) {
case " ":
- console.log("Listening...");
- let analyzer = DictationManager.Instance;
- let transcript = await analyzer.listen();
- console.log(`I heard${transcript ? `: ${transcript.toLowerCase()}` : " nothing: I thought I was still listening from an earlier session."}`);
- transcript && analyzer.execute(transcript);
+ let main = MainView.Instance;
+ main.dictationOverlayVisible = true;
+ main.isListening = true;
+ let manager = DictationManager.Instance;
+ let command = await manager.listen();
+ main.isListening = false;
+ if (!command) {
+ break;
+ }
+ command = command.toLowerCase();
+ main.dictatedPhrase = command;
+ main.dictationSuccess = await manager.execute(command);
+ setTimeout(() => {
+ main.dictationOverlayVisible = false;
+ main.dictationSuccess = undefined;
+ }, 3000);
}
return {
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index a16123476..8e57b88c3 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -24,7 +24,7 @@ div {
.jsx-parser {
width: 100%;
- height:100%;
+ height: 100%;
pointer-events: none;
border-radius: inherit;
}
@@ -119,6 +119,7 @@ button:hover {
margin-bottom: 10px;
}
}
+
.toolbar-color-picker {
background-color: $light-color;
border-radius: 5px;
@@ -128,6 +129,7 @@ button:hover {
left: -3px;
box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
}
+
.toolbar-color-button {
border-radius: 11px;
width: 22px;
@@ -146,7 +148,7 @@ button:hover {
bottom: 22px;
left: 250px;
- > label {
+ >label {
background: $dark-color;
color: $light-color;
display: inline-block;
@@ -168,15 +170,15 @@ button:hover {
transform: scale(1.15);
}
- > input {
+ >input {
display: none;
}
- > input:not(:checked)~#add-options-content {
+ >input:not(:checked)~#add-options-content {
display: none;
}
- > input:checked~label {
+ >input:checked~label {
transform: rotate(45deg);
transition: transform 0.5s;
cursor: pointer;
@@ -221,7 +223,7 @@ ul#add-options-list {
list-style: none;
padding: 5 0 0 0;
- > li {
+ >li {
display: inline-block;
padding: 0;
}
@@ -231,7 +233,7 @@ ul#add-options-list {
height: 100%;
position: absolute;
display: flex;
- flex-direction:column;
+ flex-direction: column;
}
.mainView-libraryHandle {
@@ -243,21 +245,55 @@ ul#add-options-list {
position: absolute;
z-index: 1;
}
+
.svg-inline--fa {
vertical-align: unset;
}
+
.mainView-workspace {
- height:200px;
- position:relative;
- display:flex;
+ height: 200px;
+ position: relative;
+ display: flex;
}
+
.mainView-library {
- height:75%;
- position:relative;
- display:flex;
+ height: 75%;
+ position: relative;
+ display: flex;
}
+
.mainView-recentlyClosed {
- height:25%;
- position:relative;
- display:flex;
+ height: 25%;
+ position: relative;
+ display: flex;
+}
+
+.dictation-prompt {
+ position: absolute;
+ z-index: 1000;
+ text-align: center;
+ justify-content: center;
+ align-self: center;
+ align-content: center;
+ padding: 20px;
+ background: gainsboro;
+ border-radius: 10px;
+ border: 3px solid black;
+ box-shadow: #00000044 5px 5px 10px;
+ transform: translate(-50%, -50%);
+ top: 50%;
+ font-style: italic;
+ left: 50%;
+ transition: 0.5s all ease;
+ pointer-events: none;
+}
+
+.dictation-prompt-overlay {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ background: darkslategray;
+ z-index: 999;
+ transition: 0.5s all ease;
+ pointer-events: none;
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 36ac96907..d6449cffc 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -39,7 +39,6 @@ import { FilterBox } from './search/FilterBox';
import { CollectionTreeView } from './collections/CollectionTreeView';
import { ClientUtils } from '../util/ClientUtils';
import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
-import DictationManager from '../util/DictationManager';
@observer
export class MainView extends React.Component {
@@ -48,6 +47,12 @@ export class MainView extends React.Component {
@observable private _workspacesShown: boolean = false;
@observable public pwidth: number = 0;
@observable public pheight: number = 0;
+
+ @observable private dictationState = "Listening...";
+ @observable private dictationSuccessState: boolean | undefined = undefined;
+ @observable private dictationDisplayState = false;
+ @observable private dictationListeningState = false;
+
@computed private get mainContainer(): Opt<Doc> {
return FieldValue(Cast(CurrentUserUtils.UserDocument.activeWorkspace, Doc));
}
@@ -65,6 +70,38 @@ export class MainView extends React.Component {
}
}
+ public get dictatedPhrase() {
+ return this.dictationState;
+ }
+
+ public set dictatedPhrase(value: string) {
+ runInAction(() => this.dictationState = value);
+ }
+
+ public get dictationSuccess() {
+ return this.dictationSuccessState;
+ }
+
+ public set dictationSuccess(value: boolean | undefined) {
+ runInAction(() => this.dictationSuccessState = value);
+ }
+
+ public get dictationOverlayVisible() {
+ return this.dictationDisplayState;
+ }
+
+ public set dictationOverlayVisible(value: boolean) {
+ runInAction(() => this.dictationDisplayState = value);
+ }
+
+ public get isListening() {
+ return this.dictationListeningState;
+ }
+
+ public set isListening(value: boolean) {
+ runInAction(() => this.dictationListeningState = value);
+ }
+
componentWillMount() {
var tag = document.createElement('script');
@@ -458,9 +495,23 @@ export class MainView extends React.Component {
}
render() {
+ let display = this.dictationOverlayVisible;
+ let success = this.dictationSuccess;
+ let result = this.isListening ? "Listening..." : `"${this.dictatedPhrase}"`;
return (
<div id="main-div">
- <h1>{DictationManager.Instance.current}</h1>
+ <div
+ className={"dictation-prompt"}
+ style={{
+ opacity: display ? 1 : 0,
+ background: success === undefined ? "gainsboro" : success ? "lawngreen" : "red",
+ borderColor: this.isListening ? "red" : "black",
+ }}
+ >{result}</div>
+ <div
+ className={"dictation-prompt-overlay"}
+ style={{ opacity: display ? 0.4 : 0 }}
+ />
<DocumentDecorations />
{this.mainContent}
<PreviewCursor />