Skip to content

Commit

Permalink
feat: 🎸 add useSpeech hook
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Oct 28, 2018
1 parent 0a6811d commit 3b971a2
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<br/>
- [__UI__](./docs/UI.md)
- [`useAudio`](./docs/useAudio.md) &mdash; plays audio and exposes its controls.
- [`useSpeech`](./docs/useSpeech.md) &mdash; synthesizes speech from text string.
<br/>
<br/>
- [__Animations__](./docs/Animations.md)
Expand Down
18 changes: 18 additions & 0 deletions docs/useSpeech.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# `useSpeech`

React UI hook that synthesizes human voice that speaks a given string.


## Usage

```jsx
import {useSpeech} from 'react-use';

const Demo = () => {
const state = useSpeech('Hello world!');

return (
<pre>{JSON.stringify(state, null, 2)}</pre>
);
};
```
16 changes: 16 additions & 0 deletions src/__stories__/useSpeech.story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {storiesOf} from '@storybook/react';
import * as React from 'react';
import {useSpeech} from '..';

const Demo = () => {
const state = useSpeech('Hello world!');

return (
<pre>{JSON.stringify(state, null, 2)}</pre>
);
};

storiesOf('useSpeech', module)
.add('Example', () =>
<Demo/>
)
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import useOrientation from './useOrientation';
import useRaf from './useRaf';
import useSetState from './useSetState';
import useSize from './useSize';
import useSpeech from './useSpeech';
import useSpring from './useSpring';
import useTimeout from './useTimeout';
import useTitle from './useTitle';
Expand Down Expand Up @@ -55,6 +56,7 @@ export {
useRaf,
useSetState,
useSize,
useSpeech,
useSpring,
useTimeout,
useTitle,
Expand Down
3 changes: 3 additions & 0 deletions src/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ export const useRef: UseRef = (React as any).useRef;

export type UseCallback = <T extends ((...args: any[]) => any)>(callback: T, args: any[]) => T;
export const useCallback: UseCallback = (React as any).useCallback;

export type UseMemo = <T>(fn: Function, args: any[]) => T;
export const useMemo: UseMemo = (React as any).useMemo;
2 changes: 1 addition & 1 deletion src/useLifecycles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useEffect} from './react';

const useLifecycles = (mount, unmount) => {
const useLifecycles = (mount, unmount?) => {
useEffect(() => {
if (mount) mount();
return () => {
Expand Down
6 changes: 1 addition & 5 deletions src/useMount.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import {useEffect} from './react';

const useMount = (mount) => {
useEffect(() => {
if (mount) mount();
}, []);
};
const useMount = (mount) => useEffect(mount, []);

export default useMount;
40 changes: 40 additions & 0 deletions src/useSpeech.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {useRef} from './react';
import useSetState from './useSetState';
import useMount from './useMount';

export interface SpeechState {
isPlaying: boolean;
volume: number;
}

export interface SpeechOptions {
lang?: any;
pitch?: number;
rate?: number;
voice?: any;
volume?: number;
}

const useSpeech = (text: string, opts: SpeechOptions = {}): SpeechState => {
const [state, setState] = useSetState<SpeechState>({
isPlaying: false,
volume: opts.volume || 1,
});

const uterranceRef = useRef<SpeechSynthesisUtterance | null>(null);

useMount(() => {
const utterance = new SpeechSynthesisUtterance(text);
utterance.volume = opts.volume || 1;
utterance.onstart = () => setState({isPlaying: true});
utterance.onresume = () => setState({isPlaying: true});
utterance.onend = () => setState({isPlaying: false});
utterance.onpause = () => setState({isPlaying: false});
uterranceRef.current = utterance;
window.speechSynthesis.speak(uterranceRef.current);
});

return state;
};

export default useSpeech;

0 comments on commit 3b971a2

Please sign in to comment.