diff --git a/frontends/twitch-early-access/src/App.tsx b/frontends/twitch-early-access/src/App.tsx index d811f4efec..762b465584 100644 --- a/frontends/twitch-early-access/src/App.tsx +++ b/frontends/twitch-early-access/src/App.tsx @@ -2,12 +2,13 @@ import 'bulma/css/bulma.css' import './App.css'; import React from 'react'; -import { ComponentFrame, ShowComponent } from './components/ComponentFrame'; +import { ShowComponent } from './components/ComponentFrame'; import ApiConfig from './api/ApiConfig'; -import ModeButtons from './components/ModeButtons'; import { SpeakerDetails } from './api/ApiDefinition'; import { Form } from './components/Form'; import { Speaker } from './model/Speaker'; +import { Utterance } from './model/Utterance'; +import { UtteranceHistory } from './components/UtteranceHistory'; interface Props { } @@ -18,6 +19,7 @@ interface State { speakers: Speaker[], currentText: string, currentSpeaker?: Speaker; + pastUtterances: Utterance[], } class App extends React.Component { @@ -29,6 +31,7 @@ class App extends React.Component { apiConfig: new ApiConfig(), speakers: [], currentText: "", + pastUtterances: [], }; } @@ -37,7 +40,7 @@ class App extends React.Component { } public loadSpeakers() { - const url = this.state.apiConfig.getEndpoint('/speakers'); + const url = this.state.apiConfig.getEndpoint('/voices'); fetch(url) .then(res => res.json()) @@ -84,6 +87,13 @@ class App extends React.Component { }); } + addUtterance = (utterance: Utterance) => { + let utterances = this.state.pastUtterances.concat(utterance); + this.setState({ + pastUtterances: utterances, + }) + } + public render() { return (
@@ -98,11 +108,12 @@ class App extends React.Component {
+ {/* + === TODO === -
{ currentSpeaker={this.state.currentSpeaker} updateTextCallback={this.updateText} /> + */}
+
+

Results

+

+ Your results will go here. + Please make make lots of YouTube videos before anyone else has access! +

+
+ + ); } diff --git a/frontends/twitch-early-access/src/components/Form.tsx b/frontends/twitch-early-access/src/components/Form.tsx index 5ea1bcafb6..f15e71b6ee 100644 --- a/frontends/twitch-early-access/src/components/Form.tsx +++ b/frontends/twitch-early-access/src/components/Form.tsx @@ -1,12 +1,18 @@ import React from 'react'; +import Howl from 'howler'; import { Speaker } from '../model/Speaker'; +import { SpeakRequest } from '../api/ApiDefinition'; +import ApiConfig from '../api/ApiConfig'; +import { Utterance } from '../model/Utterance'; interface Props { currentText: string, currentSpeaker?: Speaker, speakers: Speaker[], + apiConfig: ApiConfig, changeSpeakerBySlug: (speakerSlug: string) => void, changeText: (text: string) => void, + addUtteranceCallback: (utterance: Utterance) => void, } interface State { @@ -30,6 +36,57 @@ class Form extends React.Component { this.props.changeText(value); } + makeRequest = (ev: React.FormEvent) => { + const that = this; + console.log("Form Submit"); + + if (!this.props.currentText) { + return; + } + + if (this.props.currentSpeaker === undefined) { + return; + } + + const speaker = this.props.currentSpeaker; + const text = this.props.currentText; + + let request = new SpeakRequest(text, speaker!.slug); + + const url = this.props.apiConfig.getEndpoint('/speak'); + + fetch(url, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + }) + .then(res => res.blob()) + .then(blob => { + const url = window.URL.createObjectURL(blob); + + console.log('download at the audio url:'); + console.log(url); + + const sound = new Howl.Howl({ + src: [url], + format: ['wav'], + }); + + this.setState({howl: sound}); + sound.play(); + + const utterance = new Utterance(speaker, text, url, sound); + that.props.addUtteranceCallback(utterance); + }); + + ev.preventDefault(); + return false; + } + + public render() { let speakerOptions : any = []; @@ -39,27 +96,31 @@ class Form extends React.Component { return (
-
- -
-
- + +
+ +
+
+ +
-
-
- -
- +
+ +
+ +
-
+ + +
); } diff --git a/frontends/twitch-early-access/src/components/UtteranceHistory.tsx b/frontends/twitch-early-access/src/components/UtteranceHistory.tsx new file mode 100644 index 0000000000..c65150db06 --- /dev/null +++ b/frontends/twitch-early-access/src/components/UtteranceHistory.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { Utterance } from '../model/Utterance'; + +interface Props { + utterances: Utterance[], +} + +interface State { +} + +class UtteranceHistory extends React.Component { + + constructor(props: Props) { + super(props); + this.state = { + }; + } + + public render() { + let utterances = this.props.utterances.map(utterance => { + return ( +
+ +
+ ) + }); + + return ( +
+ {utterances} +
+ ); + } +} + +export { UtteranceHistory }; diff --git a/frontends/twitch-early-access/src/model/Utterance.ts b/frontends/twitch-early-access/src/model/Utterance.ts index c74b9d4ea6..4bc2b64faf 100644 --- a/frontends/twitch-early-access/src/model/Utterance.ts +++ b/frontends/twitch-early-access/src/model/Utterance.ts @@ -1,12 +1,17 @@ import { Speaker } from "./Speaker"; +import Howl from 'howler'; class Utterance { speaker: Speaker text: string + url: string + howl: Howl.Howl - constructor(speaker: Speaker, text: string) { + constructor(speaker: Speaker, text: string, url: string, howl: Howl.Howl) { this.speaker = speaker; this.text = text; + this.url = url; + this.howl = howl; } } diff --git a/tts_service/src/endpoints/speakers.rs b/tts_service/src/endpoints/speakers.rs index b7cf89918d..6ce29b2b93 100644 --- a/tts_service/src/endpoints/speakers.rs +++ b/tts_service/src/endpoints/speakers.rs @@ -29,7 +29,7 @@ pub async fn get_speakers( })) } -#[get("/early_access_speakers")] +#[get("/voices")] pub async fn get_early_access_speakers( _request: HttpRequest, app_state: Data>