add rudimentary firehose (doesn't poll)

This commit is contained in:
Brandon Thomas committed 2021-05-30 03:31:05 -04:00
1 parent ee564dd5a3
commit 543554fc56
4 files changed
+286 -163

No files matched your search

+3
View File
@@ -77,6 +77,9 @@ class ApiConfig {
return `${this.getScheme()}://${this.getNewApiHost()}/user/${username}/w2l_results`;
}
firehoseEvents() : string {
return `${this.getScheme()}://${this.getNewApiHost()}/events`;
}
private getScheme() : string {
return this.isLocalDev ? "http" : "https";
+2 -3
View File
@@ -1,5 +1,4 @@
import React from 'react';
import { FirehoseComponent } from './firehose/FirehoseComponent';
import { LoginFc } from './login/LoginFc';
import { NewTopNavFc } from './NewTopNavFc';
import { ProfileDataFc } from './profile_data/ProfileDataFc';
@@ -17,6 +16,7 @@ import { W2lTemplateListFc } from './w2l_template_list/W2lTemplateListFc';
import { W2lTemplateViewFc } from './w2l_template_view/W2lTemplateViewFc';
import { ProfileFc } from './profile/ProfileFc';
import { W2lResultViewFc } from './w2l_result_view/W2lResultViewFc';
import { FirehoseEventListFc } from './firehose/FirehoseEventListFc';
interface Props {
sessionWrapper: SessionWrapper,
@@ -50,8 +50,7 @@ class NewVocodesContainer extends React.Component<Props, State> {
<Switch>
<Route path="/firehose">
<FirehoseComponent
querySessionCallback={()=>{}}
<FirehoseEventListFc
sessionWrapper={this.props.sessionWrapper}
/>
</Route>
@@ -1,160 +0,0 @@
import React from 'react';
import { ApiConfig } from '../../v1/api/ApiConfig';
import { Mode } from '../../AppMode';
import { SessionWrapper } from '../../session/SessionWrapper';
enum FieldTriState {
EMPTY_FALSE,
FALSE,
TRUE,
}
interface Props {
sessionWrapper: SessionWrapper,
querySessionCallback : () => void,
switchModeCallback?: (mode: Mode) => void,
}
interface State {
usernameOrEmail: string,
usernameOrEmailValid: FieldTriState,
usernameOrEmailInvalidReason: string,
password: string,
passwordValid: FieldTriState,
passwordInvalidReason: string,
}
class FirehoseComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
usernameOrEmail: "",
usernameOrEmailValid: FieldTriState.EMPTY_FALSE,
usernameOrEmailInvalidReason: "",
password: "",
passwordValid: FieldTriState.EMPTY_FALSE,
passwordInvalidReason: "",
};
}
handleUsernameOrEmailChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const usernameOrEmail = (ev.target as HTMLInputElement).value;
this.setState({
usernameOrEmail: usernameOrEmail,
})
return false;
}
handlePasswordChange = (ev: React.FormEvent<HTMLInputElement>) => {
ev.preventDefault();
const password = (ev.target as HTMLInputElement).value;
this.setState({
password: password,
})
return false;
}
handleFormSubmit = (ev: React.FormEvent<HTMLFormElement>) : boolean => {
ev.preventDefault();
const api = new ApiConfig();
const endpointUrl = api.login();
const request = {
username_or_email: this.state.usernameOrEmail,
password: this.state.password,
}
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('login response', res)
if (res.success) {
console.log('querying new session');
this.props.querySessionCallback();
if (this.props.switchModeCallback !== undefined) {
this.props.switchModeCallback(Mode.SPEAK_MODE);
}
return;
}
})
.catch(e => {
//this.props.onSpeakErrorCallback();
});
return false;
}
public render() {
if (this.props.sessionWrapper.isLoggedIn()) {
return <div>Invalid view for logged in users.</div>;
}
return (
<div>
<h1 className="title is-1"> Login </h1>
<p></p>
<form onSubmit={this.handleFormSubmit}>
<div className="field">
<label className="label">Username or Email</label>
<div className="control has-icons-left has-icons-right">
<input className="input" type="text" placeholder="Username or Email" value={this.state.usernameOrEmail} onChange={this.handleUsernameOrEmailChange} />
<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"></p>*/}
</div>
<div className="field">
<label className="label">Password</label>
<div className="control has-icons-left has-icons-right">
<input className="input" type="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange} />
<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"></p>*/}
</div>
<br />
<div className="field is-grouped">
<div className="control">
<button className="button is-link is-large">Login</button>
</div>
</div>
</form>
</div>
)
}
}
export { FirehoseComponent };
@@ -0,0 +1,281 @@
import React, { useState, useEffect } from 'react';
import { ApiConfig } from '../../v1/api/ApiConfig';
import { SessionWrapper } from '../../session/SessionWrapper';
import { Link } from "react-router-dom";
import { getRandomInt } from '../../Utils';
import { GravatarFc } from '../common/GravatarFc';
interface FirehoseEventListResponsePayload {
success: boolean,
events: Array<FirehoseEvent>,
}
/*
event_token "EV:YR8HA4VCVYX9JMH5AMDFHTNRGSYGD"
event_type "w2l_template_upload_completed"
maybe_target_user_token "U:WNZCXKV1AN7XD"
maybe_target_username "brandon"
maybe_target_display_name "brandon"
maybe_target_entity_token "W2L_TPL:MJZ2SMCXX9DRNZ249VK70TWJ"
created_at "2021-05-30T06:42:39Z"
updated_at "2021-05-30T06:42:39Z"
*/
interface FirehoseEvent {
event_token: string,
event_type: string,
maybe_target_user_token?: string,
maybe_target_username?: string,
maybe_target_display_name?: string,
maybe_target_user_gravatar_hash?: string,
maybe_target_entity_token?: string,
created_at: string,
updated_at: string,
}
interface Props {
sessionWrapper: SessionWrapper,
}
function FirehoseEventListFc(props: Props) {
const [firehoseEvents, setFirehoseEvents] = useState<Array<FirehoseEvent>>([]);
useEffect(() => {
const api = new ApiConfig();
const endpointUrl = api.firehoseEvents();
fetch(endpointUrl, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
credentials: 'include',
})
.then(res => res.json())
.then(res => {
console.log('list', res);
const firehoseResponse : FirehoseEventListResponsePayload = res;
if (!firehoseResponse.success) {
return;
}
setFirehoseEvents(firehoseResponse.events)
})
.catch(e => {
// ignored
});
}, []); // NB: Empty array dependency sets to run ONLY on mount
let eventItems : Array<JSX.Element> = [];
firehoseEvents.forEach(event => {
let inner = <span />;
let userLink = undefined;
let gravatar = undefined;
if (event.maybe_target_username !== undefined) {
let link = `/profile/${event.maybe_target_username}`;
userLink = (
<Link to={link}>
{event.maybe_target_display_name}
</Link>
);
gravatar = (
<GravatarFc
size={15}
username={event.maybe_target_username}
email_hash={event.maybe_target_user_gravatar_hash}
/>
);
}
switch (event.event_type) {
case 'user_sign_up':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
signed up for vo.codes!
</span>
);
break;
case 'tts_model_upload_started':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
started TTS model upload
</span>
);
break;
case 'tts_model_upload_completed':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
completed TTS model upload
</span>
);
break;
case 'tts_inference_started':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
started TTS
</span>
);
break;
case 'tts_inference_completed':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
completed TTS
</span>
);
break;
case 'w2l_template_upload_started':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
started uploading a lipsync template.
</span>
);
break;
case 'w2l_template_upload_completed':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
finished uploading a lipsync template.
</span>
);
break;
case 'w2l_inference_started':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
started a W2L lipsync video
</span>
);
break;
case 'w2l_inference_completed':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
completed a W2L lipsync video
</span>
);
break;
case 'twitter_mention':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
mentioned us on twitter!
</span>
);
break;
case 'twitter_retweet':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
retweeted us!
</span>
);
break;
case 'discord_join':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
joined discord!
</span>
);
break;
case 'discord_message':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
sent a discord message
</span>
);
break;
case 'twitch_subscribe':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
subscribed to us on twitch!
</span>
);
break;
case 'twitch_follow':
inner = (
<span>
{gravatar}
&nbsp;
{userLink}
&nbsp;
followed us on twitch!
</span>
);
break;
default:
return;
}
eventItems.push((
<li>{inner}</li>
));
});
return (
<div>
<h1 className="title is-1"> Firehose events </h1>
<div className="content is-large">
<ul>
{eventItems}
</ul>
</div>
</div>
)
}
export { FirehoseEventListFc };