greatly improved

This commit is contained in:
Brandon Thomas committed 2021-03-17 09:51:11 -04:00
1 parent f4193046e5
commit faa75eae82
5 files changed
+167 -24

No files matched your search

+29 -4
View File
@@ -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<Props, State> {
@@ -29,6 +31,7 @@ class App extends React.Component<Props, State> {
apiConfig: new ApiConfig(),
speakers: [],
currentText: "",
pastUtterances: [],
};
}
@@ -37,7 +40,7 @@ class App extends React.Component<Props, State> {
}
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<Props, State> {
});
}
addUtterance = (utterance: Utterance) => {
let utterances = this.state.pastUtterances.concat(utterance);
this.setState({
pastUtterances: utterances,
})
}
public render() {
return (
<div>
@@ -98,11 +108,12 @@ class App extends React.Component<Props, State> {
</div>
</section>
{/*
=== TODO ===
<ModeButtons
showComponent={this.state.showComponent}
switchShowComponentCallback={this.switchComponent}
/>
<hr />
<ComponentFrame
@@ -112,13 +123,27 @@ class App extends React.Component<Props, State> {
currentSpeaker={this.state.currentSpeaker}
updateTextCallback={this.updateText}
/>
*/}
<Form
apiConfig={this.state.apiConfig}
speakers={this.state.speakers}
currentSpeaker={this.state.currentSpeaker}
currentText={this.state.currentText}
changeSpeakerBySlug={this.updateSpeakerBySlug}
changeText={this.updateText}
addUtteranceCallback={this.addUtterance}
/>
<section className="section is-small">
<h1 className="title">Results</h1>
<h2 className="subtitle">
Your results will go here.
Please make make lots of YouTube videos before anyone else has access!
</h2>
</section>
<UtteranceHistory
utterances={this.state.pastUtterances}
/>
</div>
);
}
@@ -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<Props, State> {
this.props.changeText(value);
}
makeRequest = (ev: React.FormEvent<HTMLFormElement>) => {
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<Props, State> {
return (
<div className="box">
<div className="field">
<label className="label">Speaker</label>
<div className="control">
<div className="select">
<select onChange={this.changeSpeaker}>
{speakerOptions}
</select>
<form onSubmit={this.makeRequest}>
<div className="field">
<label className="label">Speaker</label>
<div className="control">
<div className="select">
<select onChange={this.changeSpeaker}>
{speakerOptions}
</select>
</div>
</div>
</div>
</div>
<div className="field">
<label className="label">Text</label>
<div className="control">
<input
onChange={this.changeText}
className="input is-large"
type="text"
placeholder="TTS"
/>
<div className="field">
<label className="label">Text</label>
<div className="control">
<input
onChange={this.changeText}
className="input is-large"
type="text"
placeholder="TTS"
/>
</div>
</div>
</div>
<button className="button is-primary is-large">Submit</button>
</form>
</div>
);
}
@@ -0,0 +1,52 @@
import React from 'react';
import { Utterance } from '../model/Utterance';
interface Props {
utterances: Utterance[],
}
interface State {
}
class UtteranceHistory extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
};
}
public render() {
let utterances = this.props.utterances.map(utterance => {
return (
<div className="box">
<article className="media">
<div className="media-content">
<div className="content">
<p>
<strong>{utterance.speaker.name}</strong> <small>{utterance.speaker.slug}</small>
<br />
{utterance.text}
</p>
<p>
<a href="#" onClick={() => utterance.howl.play()}>Play</a>
</p>
<p>
<a href={utterance.url} target="_blank" download="vocodes-early-access.wav">Download</a>
</p>
</div>
</div>
</article>
</div>
)
});
return (
<div>
{utterances}
</div>
);
}
}
export { UtteranceHistory };
@@ -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;
}
}
+1 -1
View File
@@ -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<Arc<AppState>>