mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
upload mode (wip)
This commit is contained in:
1 parent
5ab974f346
commit
04d59933e5
7 files changed
+298
-6
No files matched your search
Generated
+29
-3
@@ -1855,6 +1855,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
|
||||
"integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ=="
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "13.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz",
|
||||
@@ -11522,6 +11527,13 @@
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"request-promise-core": {
|
||||
@@ -12272,6 +12284,13 @@
|
||||
"requires": {
|
||||
"faye-websocket": "^0.10.0",
|
||||
"uuid": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sockjs-client": {
|
||||
@@ -13468,9 +13487,9 @@
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.1.1",
|
||||
@@ -14159,6 +14178,13 @@
|
||||
"requires": {
|
||||
"ansi-colors": "^3.0.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack-manifest-plugin": {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"@types/node": "^12.12.47",
|
||||
"@types/react": "^16.9.36",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"axios": "^0.21.0",
|
||||
"bulma": "^0.9.0",
|
||||
"howler": "^2.2.0",
|
||||
@@ -21,7 +22,8 @@
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-scripts": "3.4.1",
|
||||
"typescript": "^3.7.5"
|
||||
"typescript": "^3.7.5",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "BROWSER=none react-scripts start",
|
||||
|
||||
@@ -22,6 +22,7 @@ import { SignupComponent } from './modes/signup/SignupComponent';
|
||||
import { ApiConfig } from './api/ApiConfig';
|
||||
import { SessionStateResponse } from './api/SessionState';
|
||||
import { LoginComponent } from './modes/login/LoginComponent';
|
||||
import { UploadComponent } from './modes/upload/UploadComponent';
|
||||
|
||||
interface Props {
|
||||
// Certan browsers (iPhone) have pitiful support for drawing APIs. Worse yet,
|
||||
@@ -432,6 +433,13 @@ class App extends React.Component<Props, State> {
|
||||
switchModeCallback={this.switchMode}
|
||||
/>
|
||||
break;
|
||||
case Mode.UPLOAD_MODE:
|
||||
component = <UploadComponent
|
||||
loggedIn={this.state.loggedIn}
|
||||
querySessionCallback={this.querySession}
|
||||
switchModeCallback={this.switchMode}
|
||||
/>
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<div id="main" className="mainwrap">
|
||||
|
||||
@@ -13,7 +13,7 @@ enum Mode {
|
||||
|
||||
COMMUNITY_TTS_MODE,
|
||||
COMMUNITY_VIDEO_MODE,
|
||||
UPLOAD,
|
||||
UPLOAD_MODE,
|
||||
MY_DATA_MODE,
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,14 @@ class ApiConfig {
|
||||
return `${this.getScheme()}://${this.getNewApiHost()}/session`;
|
||||
}
|
||||
|
||||
uploadTts() : string {
|
||||
return `${this.getScheme()}://${this.getNewApiHost()}/tts/upload`;
|
||||
}
|
||||
|
||||
uploadW2l() : string {
|
||||
return `${this.getScheme()}://${this.getNewApiHost()}/w2l/upload`;
|
||||
}
|
||||
|
||||
private getScheme() : string {
|
||||
return this.isLocalDev ? "http" : "https";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
import React from 'react';
|
||||
import { ApiConfig } from '../../api/ApiConfig';
|
||||
import { Mode } from '../../AppMode';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
enum UploadType {
|
||||
TTS_MODEL,
|
||||
W2L_TEMPLATE,
|
||||
}
|
||||
|
||||
enum FieldTriState {
|
||||
EMPTY_FALSE,
|
||||
FALSE,
|
||||
TRUE,
|
||||
}
|
||||
|
||||
interface Props {
|
||||
loggedIn: boolean,
|
||||
querySessionCallback : () => void,
|
||||
switchModeCallback: (mode: Mode) => void,
|
||||
}
|
||||
|
||||
interface State {
|
||||
uploadType: UploadType,
|
||||
|
||||
title: string,
|
||||
titleValid: FieldTriState,
|
||||
titleInvalidReason: string,
|
||||
|
||||
downloadUrl: string,
|
||||
downloadUrlValid: FieldTriState,
|
||||
downloadUrlInvalidReason: string,
|
||||
|
||||
idempotencyToken: string,
|
||||
}
|
||||
|
||||
class UploadComponent extends React.Component<Props, State> {
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
uploadType: UploadType.TTS_MODEL,
|
||||
|
||||
title: "",
|
||||
titleValid: FieldTriState.EMPTY_FALSE,
|
||||
titleInvalidReason: "",
|
||||
|
||||
downloadUrl: "",
|
||||
downloadUrlValid: FieldTriState.EMPTY_FALSE,
|
||||
downloadUrlInvalidReason: "",
|
||||
|
||||
idempotencyToken: "",
|
||||
};
|
||||
}
|
||||
|
||||
handleTitleChange = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
ev.preventDefault();
|
||||
|
||||
const title = (ev.target as HTMLInputElement).value;
|
||||
|
||||
this.setState({
|
||||
title: title,
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
handleDownloadUrlChange = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
ev.preventDefault();
|
||||
|
||||
const downloadUrl = (ev.target as HTMLInputElement).value;
|
||||
|
||||
this.setState({
|
||||
downloadUrl: downloadUrl,
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
handleFormSubmit = (ev: React.FormEvent<HTMLFormElement>) : boolean => {
|
||||
ev.preventDefault();
|
||||
|
||||
const api = new ApiConfig();
|
||||
let endpointUrl = "";
|
||||
|
||||
switch (this.state.uploadType) {
|
||||
case UploadType.TTS_MODEL:
|
||||
endpointUrl = api.uploadTts();
|
||||
break;
|
||||
case UploadType.W2L_TEMPLATE:
|
||||
endpointUrl = api.uploadW2l();
|
||||
break;
|
||||
}
|
||||
|
||||
let idempotency_token = this.state.idempotencyToken;
|
||||
|
||||
idempotency_token = v4();
|
||||
|
||||
const request = {
|
||||
idempotency_token: idempotency_token,
|
||||
title: this.state.title,
|
||||
download_url: this.state.downloadUrl,
|
||||
}
|
||||
|
||||
fetch(endpointUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
console.log('upload response', res)
|
||||
if (res.success) {
|
||||
this.props.switchModeCallback(Mode.SPEAK_MODE);
|
||||
return;
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
//this.props.onSpeakErrorCallback();
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
setTts = () => {
|
||||
this.setState({
|
||||
uploadType: UploadType.TTS_MODEL,
|
||||
})
|
||||
}
|
||||
|
||||
setW2l = () => {
|
||||
this.setState({
|
||||
uploadType: UploadType.W2L_TEMPLATE,
|
||||
})
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (!this.props.loggedIn) {
|
||||
return (
|
||||
<div>
|
||||
<h1>You must be logged in to upload!</h1>
|
||||
Invalid view for logged out users.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let extra = <div />;
|
||||
|
||||
if (this.state.uploadType === UploadType.TTS_MODEL) {
|
||||
extra = (
|
||||
<div className="notification is-warning">
|
||||
<strong>Over $500 in prizes!</strong>
|
||||
<p>You can help vo.codes grow by uploading Tacotron2 models.
|
||||
The person that uploads the most models will get $100,
|
||||
the person that uploads the most popular model will get $100,
|
||||
and a number of other lucky winners will be chosen at random to
|
||||
recieve cash prizes.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let title = "";
|
||||
let ttsClasses = "";
|
||||
let w2lClasses = "";
|
||||
|
||||
switch (this.state.uploadType) {
|
||||
case UploadType.TTS_MODEL:
|
||||
title = "Upload Tacotron 2 Model";
|
||||
ttsClasses = "button is-primary is-large is-light";
|
||||
w2lClasses = "button is-primary is-large";
|
||||
break;
|
||||
case UploadType.W2L_TEMPLATE:
|
||||
title = "Upload W2L Video or Image Template";
|
||||
ttsClasses = "button is-primary is-large";
|
||||
w2lClasses = "button is-primary is-large is-light";
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2> {title} </h2>
|
||||
|
||||
<div className="columns">
|
||||
<div className="column">
|
||||
<button
|
||||
className={ttsClasses}
|
||||
title="Upload TTS"
|
||||
onClick={this.setTts}
|
||||
>Upload TTS Model</button>
|
||||
</div>
|
||||
<div className="column">
|
||||
<button
|
||||
className={w2lClasses}
|
||||
title="Upload W2L"
|
||||
onClick={this.setW2l}
|
||||
>Upload Video Template</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{extra}
|
||||
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<div className="field">
|
||||
<label className="label">Title</label>
|
||||
<div className="control has-icons-left has-icons-right">
|
||||
<input className="input" type="text" placeholder="Title" value={this.state.title} onChange={this.handleTitleChange} />
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-user"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-check"></i>
|
||||
</span>
|
||||
</div>
|
||||
<p className="help">{this.state.titleInvalidReason}</p>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Download URL</label>
|
||||
<div className="control has-icons-left has-icons-right">
|
||||
<input className="input" type="password" placeholder="Download URL" value={this.state.downloadUrl} onChange={this.handleDownloadUrlChange} />
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
</div>
|
||||
<p className="help">{this.state.downloadUrlInvalidReason}</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="field is-grouped">
|
||||
<div className="control">
|
||||
<button className="button is-link is-large">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export { UploadComponent };
|
||||
@@ -65,7 +65,7 @@ function TopNav(props: Props) {
|
||||
<br />
|
||||
<a href="#community_tts" onClick={() => props.switchModeCallback(Mode.COMMUNITY_TTS_MODE)}>TTS</a>
|
||||
<a href="#community_video" onClick={() => props.switchModeCallback(Mode.COMMUNITY_VIDEO_MODE)}>Video</a>
|
||||
<a href="#upload" onClick={() => props.switchModeCallback(Mode.UPLOAD)}>Upload</a>
|
||||
<a href="#upload" onClick={() => props.switchModeCallback(Mode.UPLOAD_MODE)}>Upload</a>
|
||||
<a href="#my_data" onClick={() => props.switchModeCallback(Mode.MY_DATA_MODE)}>My Data</a>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user