animation updates to framer motion

This commit is contained in:
BFlat committed 2022-07-31 11:29:05 +07:00
1 parent 77ac380140
commit 748982ae01
26 files changed
+1752 -1943

No files matched your search

+9
View File
@@ -45,3 +45,12 @@ export const panel = {
},
hidden: { opacity: 0, y: 50 },
};
export const sessionItem = {
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.75, ease: [0.1, 0.8, 0.44, 1] },
},
hidden: { opacity: 0, x: 50 },
};
@@ -9,8 +9,8 @@ import {
faList,
faMicrophone,
} from "@fortawesome/free-solid-svg-icons";
import { distance, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, sessionItem } from "../../../data/animation";
interface Props {
ttsInferenceJobs: Array<TtsInferenceJob>;
@@ -58,13 +58,11 @@ function SessionTtsInferenceResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<div>
<Fade right duration={duration} distance={distance}>
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className={cssStyle}>{stateDescription}</div>
</Fade>
</div>
</Fade>
<div>
<motion.div className={cssStyle} variants={sessionItem}>
{stateDescription}
</motion.div>
</div>
</div>
</div>
);
@@ -79,31 +77,32 @@ function SessionTtsInferenceResultListFc(props: Props) {
<p>{job.title}</p>
<button className="delete" aria-label="delete"></button>
</div>*/}
<Fade right cascade duration={duration} distance={distance}>
<div>
<div className="panel py-4 p-3 p-lg-4 gap-4 d-flex flex-column">
<div>
<h4>
<FontAwesomeIcon icon={faMicrophone} className="me-3" />
{job.title}
</h4>
<p>{job.rawInferenceText}</p>
</div>
<audio className="w-100" controls src={audioLink}>
Your browser does not support the
<code>audio</code> element.
</audio>
<div>
<Link to={ttsPermalink} className="btn btn-primary">
<FontAwesomeIcon icon={faLink} className="me-2" />
Permalink &amp; download
</Link>
</div>
<div>
<motion.div
className="panel py-4 p-3 p-lg-4 gap-4 d-flex flex-column"
variants={sessionItem}
>
<div>
<h4>
<FontAwesomeIcon icon={faMicrophone} className="me-3" />
{job.title}
</h4>
<p>{job.rawInferenceText}</p>
</div>
</div>
</Fade>
<audio className="w-100" controls src={audioLink}>
Your browser does not support the
<code>audio</code> element.
</audio>
<div>
<Link to={ttsPermalink} className="btn btn-primary">
<FontAwesomeIcon icon={faLink} className="me-2" />
Permalink &amp; download
</Link>
</div>
</motion.div>
</div>
</div>
);
}
@@ -116,10 +115,10 @@ function SessionTtsInferenceResultListFc(props: Props) {
let title = <span />;
if (results.length !== 0) {
title = (
<h2 className="text-center text-lg-start fw-bold">
<motion.h2 className="text-center text-lg-start fw-bold" variants={item}>
<FontAwesomeIcon icon={faList} className="me-3" />
Session TTS Results
</h2>
</motion.h2>
);
}
@@ -127,7 +126,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
results.reverse();
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container-panel mb-5">
<div className="d-flex flex-column gap-4">
{title}
@@ -141,7 +140,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</div>
</div>
</motion.div>
);
}
@@ -2,8 +2,8 @@ import React from "react";
import { Link } from "react-router-dom";
import { JobState } from "@storyteller/components/src/jobs/JobStates";
import { TtsModelUploadJob } from "@storyteller/components/src/jobs/TtsModelUploadJobs";
import { distance, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, sessionItem, item } from "../../../data/animation";
interface Props {
modelUploadJobs: Array<TtsModelUploadJob>;
@@ -45,9 +45,7 @@ function SessionTtsModelUploadResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="alert alert-primary">{stateDescription}</div>
</Fade>
<div className="alert alert-primary">{stateDescription}</div>
</div>
);
} else {
@@ -55,12 +53,15 @@ function SessionTtsModelUploadResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<div className="panel py-4 p-3 p-lg-4 gap-4">
<motion.div
className="panel py-4 p-3 p-lg-4 gap-4"
variants={sessionItem}
>
Complete!
<Link to={ttsPermalink} className="btn btn-primary ms-4">
See &amp; use TTS model
</Link>
</div>
</motion.div>
</div>
);
}
@@ -69,21 +70,19 @@ function SessionTtsModelUploadResultListFc(props: Props) {
let title = <span />;
if (results.length !== 0) {
title = (
<h2 className="text-center text-lg-start fw-bold">
<motion.h2 className="text-center text-lg-start fw-bold" variants={item}>
TTS Model Upload Status
</h2>
</motion.h2>
);
}
return (
<div>
<Fade cascade right distance="100px" duration="400">
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</Fade>
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</motion.div>
);
}
@@ -4,8 +4,8 @@ import { W2lInferenceJob } from "../../../App";
import { JobState } from "@storyteller/components/src/jobs/JobStates";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faList } from "@fortawesome/free-solid-svg-icons";
import { distance, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, sessionItem } from "../../../data/animation";
interface Props {
w2lInferenceJobs: Array<W2lInferenceJob>;
@@ -47,9 +47,9 @@ function SessionW2lInferenceResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="alert alert-primary">{stateDescription}</div>
</Fade>
<motion.div className="alert alert-primary" variants={sessionItem}>
{stateDescription}
</motion.div>
</div>
);
} else {
@@ -57,12 +57,15 @@ function SessionW2lInferenceResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<div className="panel py-4 p-3 p-lg-4 gap-4">
<motion.div
className="panel py-4 p-3 p-lg-4 gap-4"
variants={sessionItem}
>
Complete!{" "}
<Link to={w2lPermalink} className="btn btn-primary ms-4">
Permalink &amp; download
</Link>
</div>
</motion.div>
</div>
);
}
@@ -71,22 +74,20 @@ function SessionW2lInferenceResultListFc(props: Props) {
let title = <span />;
if (results.length !== 0) {
title = (
<h2 className="text-center text-lg-start fw-bold">
<motion.h2 className="text-center text-lg-start fw-bold" variants={item}>
<FontAwesomeIcon icon={faList} className="me-3" />
Session W2L Results
</h2>
</motion.h2>
);
}
return (
<div>
<Fade cascade right distance="100px" duration="400">
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</Fade>
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</motion.div>
);
}
@@ -2,8 +2,8 @@ import React from "react";
import { Link } from "react-router-dom";
import { JobState } from "@storyteller/components/src/jobs/JobStates";
import { W2lTemplateUploadJob } from "@storyteller/components/src/jobs/W2lTemplateUploadJobs";
import { distance, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, sessionItem } from "../../../data/animation";
interface Props {
w2lTemplateUploadJobs: Array<W2lTemplateUploadJob>;
@@ -47,9 +47,7 @@ function SessionW2lTemplateUploadResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="alert alert-primary">{stateDescription}</div>
</Fade>
<div className="alert alert-primary">{stateDescription}</div>
</div>
);
} else {
@@ -57,12 +55,15 @@ function SessionW2lTemplateUploadResultListFc(props: Props) {
results.push(
<div key={job.jobToken}>
<div className="panel py-4 p-3 p-lg-4 gap-4">
<motion.div
className="panel py-4 p-3 p-lg-4 gap-4"
variants={sessionItem}
>
Complete!
<Link to={w2lPermalink} className="btn btn-primary ms-4">
See &amp; use template
</Link>
</div>
</motion.div>
</div>
);
}
@@ -71,21 +72,19 @@ function SessionW2lTemplateUploadResultListFc(props: Props) {
let title = <span />;
if (results.length !== 0) {
title = (
<h2 className="text-center text-lg-start fw-bold">
<motion.h2 className="text-center text-lg-start fw-bold" variants={item}>
W2L Template Upload Status
</h2>
</motion.h2>
);
}
return (
<div>
<Fade cascade right distance="100px" duration="400">
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</Fade>
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container-panel pt-4 pb-5">
<div className="pb-4">{title}</div>
<div className="d-flex flex-column gap-4">{results}</div>
</div>
</motion.div>
);
}
@@ -10,9 +10,8 @@ import {
} from "../../api/category/CreateCategory";
import { BackLink } from "../_common/BackLink";
import { FrontendUrlConfig } from "../../../common/FrontendUrlConfig";
import { distance, duration, delay, delay2 } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../data/animation";
const DEFAULT_CAN_DIRECTLY_HAVE_MODELS = true;
const DEFAULT_CAN_HAVE_SUBCATEGORIES = false;
@@ -194,95 +193,79 @@ function CreateCategoryPage(props: Props) {
if (props.sessionWrapper.canEditCategories()) {
moderateCategoriesLink = (
<>
<Fade
bottom
cascade
duration={duration}
distance={distance}
delay={delay2}
>
<div className="container pt-4 pb-5">
<Link
to={FrontendUrlConfig.moderationTtsCategoryList()}
className="btn btn-secondary w-100"
>
Moderate categories
</Link>
</div>
</Fade>
<motion.div className="container pt-4 pb-5" variants={item}>
<Link
to={FrontendUrlConfig.moderationTtsCategoryList()}
className="btn btn-secondary w-100"
>
Moderate categories
</Link>
</motion.div>
</>
);
}
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pb-4 pt-5 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold">{categoryActionName} Category</h1>
<div className="pt-3">
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pb-4 pt-5 px-md-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold" variants={item}>
{categoryActionName} Category
</motion.h1>
<motion.div className="pt-3" variants={item}>
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</motion.div>
</div>
{errorFlash}
<Fade
bottom
cascade
duration={duration}
distance={distance}
delay={delay}
>
<form onSubmit={handleFormSubmit}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Category Name</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Category Name"
value={name}
onChange={handleNameChange}
/>
</div>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Category Name</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Category Name"
value={name}
onChange={handleNameChange}
/>
</div>
<div>
<label className="sub-title">Category Type</label>
<div className="form-group">
<select
onChange={handleModelTypeChange}
className="form-select"
>
<option value="tts">TTS voice</option>
<option value="w2l">W2L video</option>
</select>
</div>
</div>
{additionalModFields}
</div>
<div>
<label className="sub-title">Category Type</label>
<div className="form-group">
<select
onChange={handleModelTypeChange}
className="form-select"
>
<option value="tts">TTS voice</option>
<option value="w2l">W2L video</option>
</select>
</div>
</div>
{additionalModFields}
</div>
</div>
</div>
<div className="container">
<button className="btn btn-primary w-100">
{categoryActionName}
</button>
</div>
</form>
</Fade>
<motion.div className="container" variants={item}>
<button className="btn btn-primary w-100">
{categoryActionName}
</button>
</motion.div>
</motion.form>
{moderateCategoriesLink}
</div>
</motion.div>
);
}
@@ -12,10 +12,9 @@ import {
LeaderboardLookupError,
} from "../../api/misc/GetLeaderboard";
import { DiscordLink2 } from "@storyteller/components/src/elements/DiscordLink2";
import { distance, delay, duration } from "../../../data/animation";
import { USE_REFRESH } from "../../../Refresh";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -144,50 +143,44 @@ function LeaderboardFc(props: Props) {
}
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<Fade cascade bottom distance={distance} duration={duration}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Leaderboard</h1>
<h3 className="mb-4">Our most frequent contributors!</h3>
<p className="lead">
Want to be on the leaderboard?{" "}
<DiscordLink2>Join our Discord</DiscordLink2> and learn more!
</p>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
Leaderboard
</motion.h1>
<motion.h3 className="mb-4" variants={item}>
Our most frequent contributors!
</motion.h3>
<motion.p className="lead" variants={item}>
Want to be on the leaderboard?{" "}
<DiscordLink2>Join our Discord</DiscordLink2> and learn more!
</motion.p>
</div>
</div>
<Fade
cascade
bottom
distance={distance}
duration={duration}
delay={delay}
>
<div className="container-panel pt-5 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">TTS Models Uploaded</h2>
<div className="py-6">
<table className="table">
<tbody>{ttsRows}</tbody>
</table>
</div>
<motion.div className="container-panel pt-5 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">TTS Models Uploaded</h2>
<div className="py-6">
<table className="table">
<tbody>{ttsRows}</tbody>
</table>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">W2L Templates Uploaded</h2>
<div className="py-6">
<table className="table">
<tbody>{w2lRows}</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">W2L Templates Uploaded</h2>
<div className="py-6">
<table className="table">
<tbody>{w2lRows}</tbody>
</table>
</div>
</div>
</Fade>
</div>
</motion.div>
</motion.div>
);
}
@@ -9,9 +9,8 @@ import {
User,
} from "../../../api/user/GetUserByUsername";
import { BackLink } from "../../_common/BackLink";
import { distance, duration, delay, delay2 } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -110,86 +109,74 @@ function ProfileBanFc(props: Props) {
let isDisabled = userData === undefined;
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<h2 className="display-5 fw-bold mb-3">Profile &amp; Preferences</h2>
<div>
<BackLink link={viewLinkUrl} text="Back to profile" />
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
Profile &amp; Preferences
</motion.h1>
<motion.div variants={item}>
<BackLink link={viewLinkUrl} text="Back to profile" />
</motion.div>
</div>
<form onSubmit={handleFormSubmit}>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<fieldset disabled={isDisabled}>
<Fade
bottom
cascade
duration={duration}
distance={distance}
delay={delay}
>
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Ban/Unban User</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Is Banned?</label>
<div className="form-group">
<select
name="default_pretrained_vocoder"
onChange={handleIsBannedChange}
value={isBanned ? "true" : "false"}
className="form-select"
>
<option value="true">Banned</option>
<option value="false">Not Banned</option>
</select>
</div>
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Ban/Unban User</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Is Banned?</label>
<div className="form-group">
<select
name="default_pretrained_vocoder"
onChange={handleIsBannedChange}
value={isBanned ? "true" : "false"}
className="form-select"
>
<option value="true">Banned</option>
<option value="false">Not Banned</option>
</select>
</div>
<div>
<label className="sub-title">
Moderator Comments (Short)
</label>
<div className="control has-icons-left has-icons-right">
<input
onChange={handleModCommentsChange}
className="form-control"
type="text"
placeholder="Moderator Comments"
value={modComments}
/>
</div>
</div>
{/*<p className="help">{invalidReason}</p>*/}
</div>
<div>
<label className="sub-title">
Moderator Comments (Short)
</label>
<div className="control has-icons-left has-icons-right">
<input
onChange={handleModCommentsChange}
className="form-control"
type="text"
placeholder="Moderator Comments"
value={modComments}
/>
</div>
</div>
{/*<p className="help">{invalidReason}</p>*/}
</div>
</div>
</div>
</Fade>
</div>
<Fade bottom duration={duration} distance={distance} delay={delay2}>
<div className="container">
<button className="btn btn-primary w-100">Update Ban</button>
</div>
</Fade>
<motion.div className="container" variants={item}>
<button className="btn btn-primary w-100">Update Ban</button>
</motion.div>
</fieldset>
</form>
</motion.form>
<Fade bottom duration={duration} distance={distance} delay={delay2}>
<div className="container py-5">
<p>Notes on banned users:</p>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</Fade>
</div>
<motion.div className="container py-5" variants={item}>
<p>Notes on banned users:</p>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</motion.div>
</motion.div>
);
}
@@ -19,8 +19,8 @@ import {
faGlobe,
} from "@fortawesome/free-solid-svg-icons";
import { BackLink } from "../../_common/BackLink";
import { distance, duration, delay, delay2 } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_VISIBILITY = "public";
@@ -234,123 +234,116 @@ function ProfileEditFc(props: Props) {
);
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold mb-3">Profile &amp; Preferences</h1>
<div>
<BackLink link={viewLinkUrl} text="Back to profile" />
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
Profile &amp; Preferences
</motion.h1>
<motion.div variants={item}>
<BackLink link={viewLinkUrl} text="Back to profile" />
</motion.div>
</div>
<form onSubmit={handleFormSubmit}>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<fieldset disabled={isDisabled}>
<Fade
bottom
cascade
delay={delay}
duration={duration}
distance={distance}
>
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Preferences</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<p>Control how the site functions.</p>
<div>
<label className="sub-title">
Audio Result Privacy&nbsp;{ttsVisibilityIcon}
</label>
<div className="form-group">
<select
name="preferred_tts_result_visibility"
onChange={handlePreferredTtsResultVisibilityChange}
value={preferredTtsResultVisibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Preferences</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<p>Control how the site functions.</p>
<div>
<label className="sub-title">
Audio Result Privacy&nbsp;{ttsVisibilityIcon}
</label>
<div className="form-group">
<select
name="preferred_tts_result_visibility"
onChange={handlePreferredTtsResultVisibilityChange}
value={preferredTtsResultVisibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
</div>
<div>
<label className="sub-title">
Video Result Privacy&nbsp;{w2lVisibilityIcon}
</label>
<div className="control select">
<select
name="preferred_w2l_result_visibility"
onChange={handlePreferredW2lResultVisibilityChange}
value={preferredW2lResultVisibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
<div>
<label className="sub-title">
Video Result Privacy&nbsp;{w2lVisibilityIcon}
</label>
<div className="control select">
<select
name="preferred_w2l_result_visibility"
onChange={handlePreferredW2lResultVisibilityChange}
value={preferredW2lResultVisibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Profile Picture</h2>
<div className="py-6">
<div className="d-flex align-items-center gap-3">
<Gravatar
size={48}
email_hash={userData.email_gravatar_hash}
/>
<div>
<h4 className="mb-0">{userData.username}</h4>
<p>@{userData.username}</p>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Profile Picture</h2>
<div className="py-6">
<div className="d-flex align-items-center gap-3">
<Gravatar
size={48}
email_hash={userData.email_gravatar_hash}
/>
<div>
<h4 className="mb-0">{userData.username}</h4>
<p>@{userData.username}</p>
</div>
<p className="mt-4">
You can set your profile picture on{" "}
<a href="https://gravatar.com">gravatar.com</a>. Use the
same email address you did to sign up for FakeYou. (In the
future, we'll support image uploads.)
</p>
</div>
<p className="mt-4">
You can set your profile picture on{" "}
<a href="https://gravatar.com">gravatar.com</a>. Use the same
email address you did to sign up for FakeYou. (In the future,
we'll support image uploads.)
</p>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Profile Details</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
<FontAwesomeIcon icon={faUser} className="me-2" />
&nbsp;Bio or whatever (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleProfileMarkdownChange}
className="form-control"
placeholder="Profile (about you)"
value={profileMarkdown}
rows={5}
/>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Profile Details</h2>
<div className="py-6">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
<FontAwesomeIcon icon={faUser} className="me-2" />
&nbsp;Bio or whatever (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleProfileMarkdownChange}
className="form-control"
placeholder="Profile (about you)"
value={profileMarkdown}
rows={5}
/>
</div>
</div>
{/*<div className="field">
{/*<div className="field">
<label className="sub-title">FakeYou Display Name</label>
<div className="form-group">
//value={downloadUrl} onChange={handleDownloadUrlChange}
@@ -370,171 +363,166 @@ function ProfileEditFc(props: Props) {
//<p className="help">{titleInvalidReason}</p>
</div>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faTwitter} className="me-2" />
Twitter Username
</label>
<div className="form-group">
<input
onChange={handleTwitterChange}
className="form-control"
type="text"
placeholder="Twitter"
value={twitter}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faTwitter} className="me-2" />
Twitter Username
</label>
<div className="form-group">
<input
onChange={handleTwitterChange}
className="form-control"
type="text"
placeholder="Twitter"
value={twitter}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faDiscord} className="me-2" />
Discord Username (don't forget the #0000)
</label>
<div className="form-group">
<input
onChange={handleDiscordChange}
className="form-control"
type="text"
placeholder="Discord"
value={discord}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faDiscord} className="me-2" />
Discord Username (don't forget the #0000)
</label>
<div className="form-group">
<input
onChange={handleDiscordChange}
className="form-control"
type="text"
placeholder="Discord"
value={discord}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faTwitch} className="me-2" />
Twitch Username
</label>
<div className="form-group">
<input
onChange={handleTwitchChange}
className="form-control"
type="text"
placeholder="Twitch"
value={twitch}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faTwitch} className="me-2" />
Twitch Username
</label>
<div className="form-group">
<input
onChange={handleTwitchChange}
className="form-control"
type="text"
placeholder="Twitch"
value={twitch}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faDollarSign} className="me-2" />
CashApp $CashTag (for reward payouts)
</label>
<div className="form-group">
<input
onChange={handleCashAppChange}
className="form-control"
type="text"
placeholder="CashApp"
value={cashApp}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faDollarSign} className="me-2" />
CashApp $CashTag (for reward payouts)
</label>
<div className="form-group">
<input
onChange={handleCashAppChange}
className="form-control"
type="text"
placeholder="CashApp"
value={cashApp}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faGithub} className="me-2" />
Github Username (I'm hiring engineers and data
scientists!)
</label>
<div className="form-group">
<input
onChange={handleGithubChange}
className="form-control"
type="text"
placeholder="Github"
value={github}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faGithub} className="me-2" />
Github Username (I'm hiring engineers and data
scientists!)
</label>
<div className="form-group">
<input
onChange={handleGithubChange}
className="form-control"
type="text"
placeholder="Github"
value={github}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faGlobe} className="me-2" />
Personal Website URL
</label>
<div className="form-group">
<input
onChange={handleWebsiteUrlChange}
className="form-control"
type="text"
placeholder="Website URL"
value={websiteUrl}
/>
<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">{downloadUrlInvalidReason}</p>*/}
<div className="field">
<label className="sub-title">
<FontAwesomeIcon icon={faGlobe} className="me-2" />
Personal Website URL
</label>
<div className="form-group">
<input
onChange={handleWebsiteUrlChange}
className="form-control"
type="text"
placeholder="Website URL"
value={websiteUrl}
/>
<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">{downloadUrlInvalidReason}</p>*/}
</div>
</div>
</div>
</div>
</Fade>
</motion.div>
<Fade bottom duration={duration} distance={distance} delay={delay2}>
<div className="container">
<button className="btn btn-primary w-100">Update</button>
</div>
</Fade>
<motion.div className="container" variants={item}>
<button className="btn btn-primary w-100">Update</button>
</motion.div>
</fieldset>
</form>
</motion.form>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container py-5">
<p>More profile and account features coming soon:</p>
<ul>
<li>Fully private models and templates</li>
<li>Sharing preferences (private, friends, auto-expire, etc.)</li>
<li>Website preferences</li>
<li>Custom avatar / profile pic uploads</li>
<li>Email change, password change, and password reset</li>
</ul>
</div>
</Fade>
</div>
<motion.div className="container py-5" variants={item}>
<p>More profile and account features coming soon:</p>
<ul>
<li>Fully private models and templates</li>
<li>Sharing preferences (private, friends, auto-expire, etc.)</li>
<li>Website preferences</li>
<li>Custom avatar / profile pic uploads</li>
<li>Email change, password change, and password reset</li>
</ul>
</motion.div>
</motion.div>
);
}
@@ -32,8 +32,8 @@ import {
faXmark,
} from "@fortawesome/free-solid-svg-icons";
import { useParams, Link } from "react-router-dom";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -257,61 +257,56 @@ function TtsEditCategoriesPage(props: Props) {
}
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 pb-4 px-lg-5 px-xl-3">
<Fade cascade bottom distance={distance} duration={duration}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Edit Categories</h1>
<h4 className="mb-4"> TTS Model: {ttsModel.title} </h4>
<p>
<BackLink link={modelLink} text="Back to model" />
</p>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
Edit Categories
</motion.h1>
<motion.h4 className="mb-4" variants={item}>
{" "}
TTS Model: {ttsModel.title}{" "}
</motion.h4>
<motion.p variants={item}>
<BackLink link={modelLink} text="Back to model" />
</motion.p>
</div>
</div>
<Fade
cascade
bottom
distance={distance}
delay={delay}
duration={duration}
>
{errorFlash}
{errorFlash}
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Current categories</h2>
<div className="py-6">
{" "}
<ul className="d-flex flex-column gap-3">
{currentCategoriesList}
</ul>
</div>
<motion.div className="container-panel py-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Current categories</h2>
<div className="py-6">
{" "}
<ul className="d-flex flex-column gap-3">
{currentCategoriesList}
</ul>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Add new category</h2>
<div className="py-6">
<div>
<div className="form-group">
<select
onChange={handleAddCategory}
value=""
className="form-select"
>
<option value="">Select category to add...</option>
{addCategoryOptions}
</select>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Add new category</h2>
<div className="py-6">
<div>
<div className="form-group">
<select
onChange={handleAddCategory}
value=""
className="form-select"
>
<option value="">Select category to add...</option>
{addCategoryOptions}
</select>
</div>
</div>
</div>
</div>
</Fade>
</div>
</motion.div>
</motion.div>
);
}
@@ -4,8 +4,8 @@ import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { useParams, Link, useHistory } from "react-router-dom";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface TtsModelViewResponsePayload {
success: boolean;
@@ -215,25 +215,19 @@ function TtsModelDeletePage(props: Props) {
}
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 pb-4 px-lg-5 px-xl-3">
<Fade cascade bottom distance={distance} duration={duration}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold mb-3">{h1Title}</h1>
<p>
<BackLink link={modelLink} text="Back to model" />
</p>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
{h1Title}
</motion.h1>
<motion.p variants={item}>
<BackLink link={modelLink} text="Back to model" />
</motion.p>
</div>
</div>
<Fade
cascade
bottom
distance={distance}
delay={delay}
duration={duration}
>
<motion.form onSubmit={handleDeleteFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
@@ -279,16 +273,14 @@ function TtsModelDeletePage(props: Props) {
</div>
</div>
<div className="container pb-5">
<form onSubmit={handleDeleteFormSubmit}>
<p>
<button className={buttonCss}>{buttonTitle}</button>
</p>
<label className="pt-4">{formLabel}</label>
</form>
</div>
</Fade>
</div>
<motion.div className="container pb-5" variants={item}>
<button className={buttonCss}>{buttonTitle}</button>
<motion.label className="pt-4" variants={item}>
{formLabel}
</motion.label>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -25,13 +25,12 @@ import {
DEFAULT_MODEL_LANGUAGE,
SUPPORTED_MODEL_LANGUAGE_TAG_TO_FULL,
} from "@storyteller/components/src/i18n/SupportedModelLanguages";
import {
TEXT_PIPELINE_NAMES,
import {
TEXT_PIPELINE_NAMES,
TEXT_PIPELINE_NAMES_FOR_MODERATORS,
} from "@storyteller/components/src/constants/TextPipeline";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_VISIBILITY = "public";
@@ -313,7 +312,9 @@ function TtsModelEditPage(props: Props) {
);
}
let usableTextPipelines = isModerator ? TEXT_PIPELINE_NAMES_FOR_MODERATORS : TEXT_PIPELINE_NAMES;
let usableTextPipelines = isModerator
? TEXT_PIPELINE_NAMES_FOR_MODERATORS
: TEXT_PIPELINE_NAMES;
let isDisabled = ttsModel === undefined;
@@ -321,161 +322,151 @@ function TtsModelEditPage(props: Props) {
visibility === "public" ? <VisibleIconFc /> : <HiddenIconFc />;
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 pb-4 px-lg-5 px-xl-3">
<Fade cascade bottom distance={distance} duration={duration}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold mb-3">Edit Model</h1>
<p>
<BackLink link={modelLink} text="Back to model" />
</p>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
Edit Model
</motion.h1>
<motion.p variants={item}>
<BackLink link={modelLink} text="Back to model" />
</motion.p>
</div>
</div>
<form onSubmit={handleFormSubmit}>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<fieldset disabled={isDisabled}>
<Fade
bottom
cascade
distance={distance}
delay={delay}
duration={duration}
>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Model Title</label>
<div className="form-group input-icon">
<FontAwesomeIcon
icon={faMicrophone}
className="form-control-feedback"
/>
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Model Title"
value={title}
/>
</div>
{/*<p className="help">{invalidReason}</p>*/}
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Model Title</label>
<div className="form-group input-icon">
<FontAwesomeIcon
icon={faMicrophone}
className="form-control-feedback"
/>
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Model Title"
value={title}
/>
</div>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={4}
/>
</div>
</div>
<div>
<label className="sub-title">Model Spoken Language</label>
<div className="form-group">
<select
onChange={handleSpokenLanguageChange}
value={fullLanguageTag}
className="form-select"
>
{Array.from(
SUPPORTED_MODEL_LANGUAGE_TAG_TO_FULL,
([languageTag, description]) => {
return (
<option key={languageTag} value={languageTag}>
{description}
</option>
);
}
)}
</select>
</div>
</div>
<div>
<label className="sub-title">Text Pipeline</label>
<div className="form-group">
<select
name="text_pipeline_type"
onChange={handleTextPipelineChange}
value={textPipelineType || "legacy_fakeyou"}
className="form-select"
>
{Array.from(
usableTextPipelines,
([textPipelineType, description]) => {
return (
<option
key={textPipelineType}
value={textPipelineType}
>
{description}
</option>
);
}
)}
</select>
</div>
</div>
<div>
<label className="sub-title">Default vocoder</label>
<div className="form-group">
<select
name="default_pretrained_vocoder"
onChange={handleDefaultPretrainedVocoderChange}
value={defaultPretrainedVocoder}
className="form-select"
>
<option value="hifigan-superres">
HiFi-Gan (typically sounds best)
</option>
<option value="waveglow">WaveGlow</option>
</select>
</div>
</div>
<div>
<label className="sub-title">
Model Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
</div>
{optionalModeratorFields}
{/*<p className="help">{invalidReason}</p>*/}
</div>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={4}
/>
</div>
</div>
<div>
<label className="sub-title">Model Spoken Language</label>
<div className="form-group">
<select
onChange={handleSpokenLanguageChange}
value={fullLanguageTag}
className="form-select"
>
{Array.from(
SUPPORTED_MODEL_LANGUAGE_TAG_TO_FULL,
([languageTag, description]) => {
return (
<option key={languageTag} value={languageTag}>
{description}
</option>
);
}
)}
</select>
</div>
</div>
<div>
<label className="sub-title">Text Pipeline</label>
<div className="form-group">
<select
name="text_pipeline_type"
onChange={handleTextPipelineChange}
value={textPipelineType || "legacy_fakeyou"}
className="form-select"
>
{Array.from(
usableTextPipelines,
([textPipelineType, description]) => {
return (
<option
key={textPipelineType}
value={textPipelineType}
>
{description}
</option>
);
}
)}
</select>
</div>
</div>
<div>
<label className="sub-title">Default vocoder</label>
<div className="form-group">
<select
name="default_pretrained_vocoder"
onChange={handleDefaultPretrainedVocoderChange}
value={defaultPretrainedVocoder}
className="form-select"
>
<option value="hifigan-superres">
HiFi-Gan (typically sounds best)
</option>
<option value="waveglow">WaveGlow</option>
</select>
</div>
</div>
<div>
<label className="sub-title">
Model Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-select"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
</div>
{optionalModeratorFields}
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Update</button>
</div>
</Fade>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Update</button>
</motion.div>
</fieldset>
</form>
</div>
</motion.form>
</motion.div>
);
}
@@ -6,7 +6,10 @@ import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapp
import { Gravatar } from "@storyteller/components/src/elements/Gravatar";
import { LanguageCodeToDescriptionWithDefault } from "@storyteller/components/src/i18n/SupportedModelLanguages";
import { TtsInferenceJob } from "@storyteller/components/src/jobs/TtsInferenceJobs";
import { TEXT_PIPELINE_NAMES, TEXT_PIPELINE_NAMES_FOR_MODERATORS } from "@storyteller/components/src/constants/TextPipeline";
import {
TEXT_PIPELINE_NAMES,
TEXT_PIPELINE_NAMES_FOR_MODERATORS,
} from "@storyteller/components/src/constants/TextPipeline";
import { useParams, Link } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
@@ -43,8 +46,8 @@ import {
faVolumeHigh,
faDeleteLeft,
} from "@fortawesome/free-solid-svg-icons";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -303,20 +306,18 @@ function TtsModelViewPage(props: Props) {
if (!!ttsModel?.description_rendered_html) {
modelDescription = (
<>
<Fade bottom distance={distance} delay={delay} duration={duration}>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Description</h2>
<div className="py-6">
<p
dangerouslySetInnerHTML={{
__html: ttsModel?.description_rendered_html || "",
}}
/>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Description</h2>
<div className="py-6">
<p
dangerouslySetInnerHTML={{
__html: ttsModel?.description_rendered_html || "",
}}
/>
</div>
</div>
</Fade>
</motion.div>
</>
);
}
@@ -377,17 +378,15 @@ function TtsModelViewPage(props: Props) {
modelCategoriesSection = (
<>
<Fade bottom distance={distance} delay={delay} duration={duration}>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Categories</h2>
<div className="py-6">
{modelCategories}
{editModelCategoriesButton}
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Categories</h2>
<div className="py-6">
{modelCategories}
{editModelCategoriesButton}
</div>
</div>
</Fade>
</motion.div>
</>
);
}
@@ -437,10 +436,13 @@ function TtsModelViewPage(props: Props) {
let textPipelineName = UNKNOWN;
let usableTextPipelines = canEditModel ? TEXT_PIPELINE_NAMES_FOR_MODERATORS : TEXT_PIPELINE_NAMES;
let usableTextPipelines = canEditModel
? TEXT_PIPELINE_NAMES_FOR_MODERATORS
: TEXT_PIPELINE_NAMES;
if (!!textPipelineConfigured) {
textPipelineName = usableTextPipelines.get(textPipelineConfigured) || UNKNOWN;
textPipelineName =
usableTextPipelines.get(textPipelineConfigured) || UNKNOWN;
} else {
let configuredName = usableTextPipelines.get(textPipelineUsed) || UNKNOWN;
textPipelineName = `Not set; using default of ${configuredName}`;
@@ -512,132 +514,125 @@ function TtsModelViewPage(props: Props) {
}
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5">
<Fade cascade bottom distance={distance} duration={duration}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold mb-4 text-center text-lg-start">
{title}
</h1>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1
className="display-5 fw-bold mb-4 text-center text-lg-start"
variants={item}
>
{title}
</motion.h1>
</div>
</div>
<div>{modelDescription}</div>
<div>{modelCategoriesSection}</div>
<Fade
cascade
bottom
distance={distance}
delay={delay}
duration={duration}
>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{ttsModel?.title}</td>
</tr>
<tr>
<th>Spoken Language</th>
<td>{language}</td>
</tr>
<tr>
<th>Model type</th>
<td>{ttsModel?.tts_model_type}</td>
</tr>
<tr>
<th>Default vocoder</th>
<td>{defaultVocoder}</td>
</tr>
<tr>
<th>Text pipeline</th>
<td>{textPipelineName}</td>
</tr>
<tr>
<th>Upload date (UTC)</th>
<td>{ttsModel?.created_at}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>
Bot TTS Command for <FontAwesomeIcon icon={faDiscord} /> /{" "}
<FontAwesomeIcon icon={faTwitch} />
</th>
<td>{discordCommand}</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{ttsModel?.title}</td>
</tr>
<tr>
<th>Spoken Language</th>
<td>{language}</td>
</tr>
<tr>
<th>Model type</th>
<td>{ttsModel?.tts_model_type}</td>
</tr>
<tr>
<th>Default vocoder</th>
<td>{defaultVocoder}</td>
</tr>
<tr>
<th>Text pipeline</th>
<td>{textPipelineName}</td>
</tr>
<tr>
<th>Upload date (UTC)</th>
<td>{ttsModel?.created_at}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>
Bot TTS Command for <FontAwesomeIcon icon={faDiscord} /> /{" "}
<FontAwesomeIcon icon={faTwitch} />
</th>
<td>{discordCommand}</td>
</tr>
</tbody>
</table>
</div>
</div>
</motion.div>
<div>{moderatorRows}</div>
<motion.div variants={panel}>{moderatorRows}</motion.div>
<div className="container pb-5">
<div className="d-flex flex-column flex-md-row gap-3">
{editModelButton}
{deleteModelButton}
<motion.div className="container pb-4" variants={panel}>
<div className="d-flex flex-column flex-md-row gap-3">
{editModelButton}
{deleteModelButton}
</div>
</motion.div>
<motion.div className="container-panel py-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Use Model</h2>
<div className="py-6">
<form onSubmit={handleFormSubmit}>
<textarea
onChange={handleChangeText}
value={props.textBuffer}
className="form-control fs-5"
placeholder="Textual shenanigans go here..."
rows={6}
></textarea>
<div className="d-flex gap-3 mt-4 pt-3 flex-column flex-md-row">
<button className="btn btn-primary w-100">
<FontAwesomeIcon icon={faVolumeHigh} className="me-2" />
Speak
</button>
<button
className="btn btn-destructive w-100"
onClick={handleClearClick}
>
<FontAwesomeIcon icon={faDeleteLeft} className="me-2" />
Clear
</button>
</div>
</form>
</div>
</div>
</motion.div>
<div className="container-panel py-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Use Model</h2>
<div className="py-6">
<form onSubmit={handleFormSubmit}>
<textarea
onChange={handleChangeText}
value={props.textBuffer}
className="form-control fs-5"
placeholder="Textual shenanigans go here..."
rows={6}
></textarea>
<div className="d-flex gap-3 mt-4 pt-3 flex-column flex-md-row">
<button className="btn btn-primary w-100">
<FontAwesomeIcon icon={faVolumeHigh} className="me-2" />
Speak
</button>
<button
className="btn btn-destructive w-100"
onClick={handleClearClick}
>
<FontAwesomeIcon icon={faDeleteLeft} className="me-2" />
Clear
</button>
</div>
</form>
</div>
</div>
</div>
<div className="container pb-5">
<BackLink link="/" text="Back to all models" />
</div>
</Fade>
<motion.div className="container pb-5" variants={item}>
<BackLink link="/" text="Back to all models" />
</motion.div>
<SessionTtsInferenceResultListFc
ttsInferenceJobs={props.ttsInferenceJobs}
/>
</div>
</motion.div>
);
}
@@ -4,9 +4,8 @@ import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapp
import { useParams, Link, useHistory } from "react-router-dom";
import { Gravatar } from "@storyteller/components/src/elements/Gravatar";
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
import { distance, delay, delay2, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface TtsInferenceResultResponsePayload {
success: boolean;
@@ -188,18 +187,18 @@ function TtsResultDeletePage(props: Props) {
: "Delete TTS Result (hides from everyone but mods)";
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold mb-3">{h1Title}</h1>
<div>
<Link to={resultLink}>&lt; Back to result</Link>
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
{h1Title}
</motion.h1>
<motion.div variants={item}>
<Link to={resultLink}>&lt; Back to result</Link>
</motion.div>
</div>
<div className="container-panel pt-4 pb-5">
<Fade bottom duration={duration} distance={distance} delay={delay}>
<motion.form onSubmit={handleDeleteFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 p-lg-4">
<table className="table tts-result-table">
<thead>
@@ -240,24 +239,16 @@ function TtsResultDeletePage(props: Props) {
</tbody>
</table>
</div>
</Fade>
</div>
</div>
<form onSubmit={handleDeleteFormSubmit}>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay2}
>
<div className="container pb-5">
<button className=" btn btn-primary w-100">{buttonTitle}</button>
<p className="mt-4">{formLabel}</p>
</div>
</Fade>
</form>
</div>
<motion.div className="container pb-5" variants={item}>
<button className=" btn btn-primary w-100">{buttonTitle}</button>
<motion.p className="mt-4" variants={item}>
{formLabel}
</motion.p>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -5,9 +5,8 @@ import { useParams, Link, useHistory } from "react-router-dom";
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
import { distance, delay, delay2, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_VISIBILITY = "public";
@@ -151,56 +150,46 @@ function TtsResultEditPage(props: Props) {
);
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold mb-3">Edit Result Visibility</h1>
<div>
<Link to={resultLink}>&lt; Back to result</Link>
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
Edit Result Visibility
</motion.h1>
<motion.div variants={item}>
<Link to={resultLink}>&lt; Back to result</Link>
</motion.div>
</div>
<form onSubmit={handleFormSubmit}>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<fieldset disabled={isDisabled}>
<div className="container-panel pt-4 pb-5">
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="panel p-3 py-4 p-lg-4">
<div>
<label className="sub-title">
Result Visibility&nbsp;{visibilityIcon}
</label>
<div className="control select">
<select
className="form-select"
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
<div className="panel p-3 py-4 p-lg-4">
<div>
<label className="sub-title">
Result Visibility&nbsp;{visibilityIcon}
</label>
<div className="control select">
<select
className="form-select"
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
</div>
</Fade>
</div>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay2}
>
<div className="container">
<button className="btn btn-primary w-100 mb-5">Update</button>
</div>
</Fade>
</div>
<motion.div className="container" variants={item}>
<button className="btn btn-primary w-100 mb-5">Update</button>
</motion.div>
</fieldset>
</form>
</div>
</motion.form>
</motion.div>
);
}
@@ -23,9 +23,8 @@ import {
faEye,
faEyeSlash,
} from "@fortawesome/free-solid-svg-icons";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -125,64 +124,56 @@ function TtsResultViewPage(props: Props) {
) {
moderatorRows = (
<>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay}
>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Model creator is banned</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.model_creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator is banned (if user)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_is_banned_if_user
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator IP address</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_ip_address || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.mod_deleted_at || "not deleted"}
</td>
</tr>
<tr>
<th>Result creator deleted at (UTC)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_deleted_at || "not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Model creator is banned</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.model_creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator is banned (if user)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_is_banned_if_user
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator IP address</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_ip_address || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.mod_deleted_at || "not deleted"}
</td>
</tr>
<tr>
<th>Result creator deleted at (UTC)</th>
<td>
{ttsInferenceResult?.maybe_moderator_fields
?.result_creator_deleted_at || "not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</Fade>
</div>
</>
);
}
@@ -297,42 +288,36 @@ function TtsResultViewPage(props: Props) {
}
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container py-5">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold mb-4 text-center text-lg-start">
{headingTitle}
</h1>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5">
<div className="d-flex flex-column">
<motion.h1
className="display-5 fw-bold mb-4 text-center text-lg-start"
variants={item}
>
{headingTitle}
</motion.h1>
</div>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
{subtitle}
<div className="py-6">
<TtsResultAudioPlayerFc ttsResult={ttsInferenceResult} />
<a
className=" btn btn-primary w-100 mt-4"
href={audioLink}
download={audioDownloadFilename}
>
<FontAwesomeIcon icon={faDownload} className="me-2" />
Download File{" "}
</a>
</div>
</div>
</Fade>
</motion.div>
<Fade
cascade
bottom
duration={duration}
delay={delay}
distance={distance}
>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
{subtitle}
<div className="py-6">
<TtsResultAudioPlayerFc ttsResult={ttsInferenceResult} />
<a
className=" btn btn-primary w-100 mt-4"
href={audioLink}
download={audioDownloadFilename}
>
<FontAwesomeIcon icon={faDownload} className="me-2" />
Download File{" "}
</a>
</div>
</div>
</div>
{/* Without wavesurfer,
{/* Without wavesurfer,
<audio
controls
src={audioLink}>
@@ -340,97 +325,87 @@ function TtsResultViewPage(props: Props) {
<code>audio</code> element.
</audio>*/}
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Spectrogram</h2>
<SpectrogramFc spectrogramJsonLink={spectrogramLink} />
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Spectrogram</h2>
<SpectrogramFc spectrogramJsonLink={spectrogramLink} />
</div>
</motion.div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Result Details</h2>
<div className="py-6">
<table className="table tts-result-table">
<tbody>
<tr>
<th scope="row">Original text</th>
<td className="overflow-fix">
{ttsInferenceResult.raw_inference_text}
</td>
</tr>
<tr>
<th scope="row">Audio creator</th>
<td>{creatorDetails}</td>
</tr>
<tr>
<th scope="row">Audio duration</th>
<td>{durationSeconds} seconds</td>
</tr>
<tr>
<th scope="row">Visibility</th>
<td>{resultVisibility}</td>
</tr>
</tbody>
</table>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Result Details</h2>
<div className="py-6">
<table className="table tts-result-table">
<tbody>
<tr>
<th scope="row">Original text</th>
<td className="overflow-fix">
{ttsInferenceResult.raw_inference_text}
</td>
</tr>
<tr>
<th scope="row">Audio creator</th>
<td>{creatorDetails}</td>
</tr>
<tr>
<th scope="row">Audio duration</th>
<td>{durationSeconds} seconds</td>
</tr>
<tr>
<th scope="row">Visibility</th>
<td>{resultVisibility}</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Used</h2>
<div className="py-6">
<table className="table tts-result-table">
<tbody>
<tr>
<th scope="row">Model name</th>
<td>
<Link to={modelLink}>{modelName}</Link>
</td>
</tr>
<tr>
<th scope="row">Model creator</th>
<td>{modelCreatorDetails}</td>
</tr>
<tr>
<th scope="row">Vocoder used</th>
<td>{vocoderUsed}</td>
</tr>
<tr>
<th scope="row">Worker</th>
<td>{ttsInferenceResult.generated_by_worker}</td>
</tr>
{debugRows}
</tbody>
</table>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Used</h2>
<div className="py-6">
<table className="table tts-result-table">
<tbody>
<tr>
<th scope="row">Model name</th>
<td>
<Link to={modelLink}>{modelName}</Link>
</td>
</tr>
<tr>
<th scope="row">Model creator</th>
<td>{modelCreatorDetails}</td>
</tr>
<tr>
<th scope="row">Vocoder used</th>
<td>{vocoderUsed}</td>
</tr>
<tr>
<th scope="row">Worker</th>
<td>{ttsInferenceResult.generated_by_worker}</td>
</tr>
<motion.div variants={panel}>{moderatorRows}</motion.div>
{debugRows}
</tbody>
</table>
</div>
</div>
<motion.div className="container pb-5" variants={item}>
<div className="d-flex flex-column flex-md-row gap-3 mb-4">
{editButton}
{deleteButton}
</div>
</Fade>
<div>{moderatorRows}</div>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay}
>
<div className="container pb-5">
<div className="d-flex flex-column flex-md-row gap-3 mb-4">
{editButton}
{deleteButton}
</div>
<p className="text-center text-lg-start">
<ReportDiscordLinkFc />
</p>
</div>
</Fade>
</div>
<motion.p className="text-center text-lg-start" variants={item}>
<ReportDiscordLinkFc />
</motion.p>
</motion.div>
</motion.div>
);
}
@@ -9,9 +9,8 @@ import { v4 as uuidv4 } from "uuid";
import { BackLink } from "../_common/BackLink";
import { Link } from "react-router-dom";
import { FrontendUrlConfig } from "../../../common/FrontendUrlConfig";
import { distance, delay, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -111,128 +110,125 @@ function UploadTtsModelFc(props: Props) {
};
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-md-4 px-lg-5 px-xl-3">
<Fade bottom cascade duration={duration} distance={distance}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Upload Voice (TTS Model)</h1>
<h4>This works just like YouTube!</h4>
<div className="my-3">
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</div>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
Upload Voice (TTS Model)
</motion.h1>
<motion.h4 variants={item}>This works just like YouTube!</motion.h4>
<motion.div className="my-3" variants={item}>
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</motion.div>
</div>
</div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container px-md-4 px-lg-5 px-xl-3">
<div className="alert alert-primary">
<strong>Content Creator Rewards!</strong>
{/*<p>You can help FakeYou grow by uploading Tacotron2 models.
<motion.div className="container px-md-4 px-lg-5 px-xl-3" variants={item}>
<div className="alert alert-primary">
<strong>Content Creator Rewards!</strong>
{/*<p>You can help FakeYou 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. Uploaders will also get queue priority!</p>*/}
<div>
As you upload and help us grow, you'll earn unique perks such as
featured roles in Discord, queue priority, and more!
</div>
<div>
As you upload and help us grow, you'll earn unique perks such as
featured roles in Discord, queue priority, and more!
</div>
</div>
</Fade>
</motion.div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container pt-3 d-flex flex-column gap-3 px-md-4 px-lg-5 px-xl-3">
<p>
If you're new to voice cloning, join our{" "}
<span>
<DiscordLink />
</span>{" "}
to get started. We have a friendly community that can help you start
creating your own voices of your favorite characters.
</p>
<motion.div
className="container pt-3 d-flex flex-column gap-3 px-md-4 px-lg-5 px-xl-3"
variants={item}
>
<p>
If you're new to voice cloning, join our{" "}
<span>
<DiscordLink />
</span>{" "}
to get started. We have a friendly community that can help you start
creating your own voices of your favorite characters.
</p>
{/* TODO TEMP (2022-03-08) <p>
{/* TODO TEMP (2022-03-08) <p>
FakeYou currently supports <em>Tacotron 2</em>, GlowTTS, and a custom synthesizer architecture
that we intend to open source. We'll soon add TalkNet, custom vocoder uploads, and more model
architectures.
</p>*/}
<p>
Once your voice is successfully uploaded, you'll be able to start
using it and sharing it with others. You'll also be able to edit the
title, tags, and vocoder used, so don't worry if you typo something.
</p>
<p>
Once your voice is successfully uploaded, you'll be able to start
using it and sharing it with others. You'll also be able to edit the
title, tags, and vocoder used, so don't worry if you typo something.
</p>
{/* TODO TEMP (2022-03-08) <p>
{/* TODO TEMP (2022-03-08) <p>
Please do not upload voices that you didn't train yourself or voices of individuals
who wish to not be voice cloned. We'll post a list of banned voices soon.
</p>*/}
</div>
</Fade>
</motion.div>
<form onSubmit={handleFormSubmit}>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Goku (Sean Schemmel)"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
</div>
{/*
https://drive.google.com/file/d/{TOKEN}/view?usp=sharing
*/}
<div>
<label className="sub-title">
Download URL, eg. Google Drive link
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Goku (Sean Schemmel)"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
</div>
{/*<div className="field is-grouped">
{/*
https://drive.google.com/file/d/{TOKEN}/view?usp=sharing
*/}
<div>
<label className="sub-title">
Download URL, eg. Google Drive link
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
</div>
</div>
{/*<div className="field is-grouped">
<div className="control">
<button className="button is-link is-large is-fullwidth">Upload</button>
</div>
</div>*/}
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Upload</button>
</div>
</Fade>
</form>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Upload</button>
</motion.div>
</motion.form>
<SessionTtsModelUploadResultListFc
modelUploadJobs={props.ttsModelUploadJobs}
/>
</div>
</motion.div>
);
}
@@ -7,8 +7,8 @@ import { v4 as uuidv4 } from "uuid";
import { SessionW2lTemplateUploadResultListFc } from "../_common/SessionW2lTemplateUploadResultsListFc";
import { BackLink } from "../_common/BackLink";
import { FrontendUrlConfig } from "../../../common/FrontendUrlConfig";
import { distance, delay, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../data/animation";
interface W2lTemplateUploadJobResponsePayload {
success: boolean;
@@ -91,91 +91,86 @@ function UploadW2lPhotoFc(props: Props) {
};
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-3 px-md-4 px-lg-5 px-xl-3">
<Fade bottom cascade duration={duration} distance={distance}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold"> Upload Photo (w2l template) </h1>
<div className="my-3">
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</div>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
Upload Photo (w2l template)
</motion.h1>
<motion.div className="my-3" variants={item}>
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</motion.div>
</div>
</div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container px-md-4 px-lg-5 px-xl-3">
<p>
The photos you upload can be used for lipsyncing with audio using
the Wav2Lip model. In the future, you'll be able to use these for
first-order-model and much more!
</p>
</div>
</Fade>
<motion.div className="container px-md-4 px-lg-5 px-xl-3" variants={item}>
<p>
The photos you upload can be used for lipsyncing with audio using the
Wav2Lip model. In the future, you'll be able to use these for
first-order-model and much more!
</p>
</motion.div>
<form onSubmit={handleFormSubmit}>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Dr. Phil stares into your soul"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Dr. Phil stares into your soul"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
</div>
{/*
{/*
https://drive.google.com/file/d/{TOKEN}/view?usp=sharing
*/}
<div>
<label className="sub-title">
Download URL, eg.{" "}
<code>https://i.imgur.com/lKaQ4Er.jpg</code>
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
<div>
<label className="sub-title">
Download URL, eg. <code>https://i.imgur.com/lKaQ4Er.jpg</code>
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
</div>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Upload</button>
</div>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Upload</button>
</motion.div>
{/*<div className="field is-grouped">
{/*<div className="field is-grouped">
<div className="control">
<button className="button is-link is-large is-fullwidth">Upload</button>
</div>
</div>*/}
</Fade>
</form>
</motion.form>
<SessionW2lTemplateUploadResultListFc
w2lTemplateUploadJobs={props.w2lTemplateUploadJobs}
/>
</div>
</motion.div>
);
}
@@ -7,8 +7,8 @@ import { useHistory } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import { BackLink } from "../_common/BackLink";
import { FrontendUrlConfig } from "../../../common/FrontendUrlConfig";
import { distance, delay, duration } from "../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../data/animation";
interface W2lTemplateUploadJobResponsePayload {
success: boolean;
@@ -91,89 +91,85 @@ function UploadW2lVideoFc(props: Props) {
};
return (
<div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-3 px-md-4 px-lg-5 px-xl-3">
<Fade bottom cascade duration={duration} distance={distance}>
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Upload Video (w2l template)</h1>
<div className="my-3">
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</div>
</div>
</Fade>
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
Upload Video (w2l template)
</motion.h1>
<motion.div className="my-3" variants={item}>
<BackLink
link={FrontendUrlConfig.contributePage()}
text="Back to contribute page"
/>
</motion.div>
</div>
</div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container px-md-4 px-lg-5 px-xl-3">
<p>
The videos you upload can be used for lipsyncing with audio using
the Wav2Lip model.
</p>
</div>
</Fade>
<motion.div className="container px-md-4 px-lg-5 px-xl-3" variants={item}>
<p>
The videos you upload can be used for lipsyncing with audio using the
Wav2Lip model.
</p>
</motion.div>
<form onSubmit={handleFormSubmit}>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Morshu tells you things"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<div className="container-panel py-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">
Title, eg. "Morshu tells you things"
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Title"
value={title}
onChange={handleTitleChange}
/>
</div>
<p className="help">{titleInvalidReason}</p>
</div>
{/*
{/*
https://drive.google.com/file/d/{TOKEN}/view?usp=sharing
*/}
<div>
<label className="sub-title">
Download URL, eg. Google Drive link
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
<div>
<label className="sub-title">
Download URL, eg. Google Drive link
</label>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Download URL"
value={downloadUrl}
onChange={handleDownloadUrlChange}
/>
</div>
<p className="help">{downloadUrlInvalidReason}</p>
</div>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Upload</button>
</div>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Upload</button>
</motion.div>
{/*<div className="field is-grouped">
{/*<div className="field is-grouped">
<div className="control">
<button className="button is-link is-large is-fullwidth">Upload</button>
</div>
</div>*/}
</Fade>
</form>
</motion.form>
<SessionW2lTemplateUploadResultListFc
w2lTemplateUploadJobs={props.w2lTemplateUploadJobs}
/>
</div>
</motion.div>
);
}
@@ -8,9 +8,8 @@ import {
GetW2lResultIsOk,
W2lResult,
} from "../../../api/w2l/GetW2lResult";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -105,23 +104,17 @@ function W2lResultDeleteFc(props: Props) {
const durationSeconds = (w2lInferenceResult?.duration_millis || 0) / 1000;
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold">{h1Title}</h1>
<div className="pt-3">
<Link to={templateResultLink}>&lt; Back to result</Link>
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-md-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold" variants={item}>
{h1Title}
</motion.h1>
<motion.div className="pt-3" variants={item}>
<Link to={templateResultLink}>&lt; Back to result</Link>
</motion.div>
</div>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay}
>
<motion.form onSubmit={handleDeleteFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
@@ -153,14 +146,14 @@ function W2lResultDeleteFc(props: Props) {
</div>
</div>
<div className="container pb-5">
<form onSubmit={handleDeleteFormSubmit}>
<button className={buttonCss}>{buttonTitle}</button>
<p className="pt-4">{formLabel}</p>
</form>
</div>
</Fade>
</div>
<motion.div className="container pb-5" variants={item}>
<button className={buttonCss}>{buttonTitle}</button>
<motion.p className="pt-4" variants={item}>
{formLabel}
</motion.p>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -5,9 +5,8 @@ import { useParams, Link, useHistory } from "react-router-dom";
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
import { VisibleIconFc } from "../../_icons/VisibleIcon";
import { HiddenIconFc } from "../../_icons/HiddenIcon";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_VISIBILITY = "public";
@@ -147,54 +146,46 @@ function W2lResultEditFc(props: Props) {
visibility === "public" ? <VisibleIconFc /> : <HiddenIconFc />;
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container pb-4 pt-5 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold">Edit Result Visibility</h1>
<div className="pt-3">
<Link to={resultLink}>&lt; Back to result </Link>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pb-4 pt-5 px-md-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold" variants={item}>
Edit Result Visibility
</motion.h1>
<motion.div className="pt-3" variants={item}>
<Link to={resultLink}>&lt; Back to result </Link>
</motion.div>
</div>
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<fieldset disabled={isDisabled}>
<div>
<label className="sub-title">
Result Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
</div>
</fieldset>
</div>
</div>
</Fade>
<Fade
cascade
bottom
duration={duration}
distance={distance}
delay={delay}
>
<form onSubmit={handleFormSubmit}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<fieldset disabled={isDisabled}>
<div>
<label className="sub-title">
Result Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
</div>
</fieldset>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Update</button>
</div>
</form>
</Fade>
</div>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Update</button>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -17,9 +17,8 @@ import {
import { MetaTags } from "../../../../common/MetaTags";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faDownload, faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -95,58 +94,56 @@ function W2lResultViewFc(props: Props) {
) {
moderatorRows = (
<>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Template creator is banned</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.template_creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator is banned (if user)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_is_banned_if_user
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator IP address</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_ip_address || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.mod_deleted_at || "not deleted"}
</td>
</tr>
<tr>
<th>Result creator deleted at (UTC)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_deleted_at || "not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Template creator is banned</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.template_creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator is banned (if user)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_is_banned_if_user
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Result creator IP address</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_ip_address || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.mod_deleted_at || "not deleted"}
</td>
</tr>
<tr>
<th>Result creator deleted at (UTC)</th>
<td>
{w2lInferenceResult?.maybe_moderator_fields
?.result_creator_deleted_at || "not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</Fade>
</div>
</>
);
}
@@ -256,102 +253,100 @@ function W2lResultViewFc(props: Props) {
);
}
return (
<div>
<Fade cascade bottom duration={duration} distance={distance}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold text-center text-lg-start">
Lipsync Result
</h1>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<motion.h1
className="display-5 fw-bold text-center text-lg-start"
variants={item}
>
Lipsync Result
</motion.h1>
</div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container">
<video width="100%" height="auto" controls={true} className="rounded">
<source src={videoLink} />
Your device doesn't support video.
</video>
</div>
<motion.div className="container" variants={item}>
<video width="100%" height="auto" controls={true} className="rounded">
<source src={videoLink} />
Your device doesn't support video.
</video>
</motion.div>
<div className="container pt-4 pb-5">
<a
className="btn btn-primary w-100"
href={videoLink}
download={videoDownloadFilename}
>
{" "}
<FontAwesomeIcon icon={faDownload} className="me-2" />
Download File
</a>
</div>
<motion.div className="container pt-4 pb-5" variants={item}>
<a
className="btn btn-primary w-100"
href={videoLink}
download={videoDownloadFilename}
>
{" "}
<FontAwesomeIcon icon={faDownload} className="me-2" />
Download File
</a>
</motion.div>
<div className="container-panel pt-5 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Result Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator</th>
<td>{creatorDetails}</td>
</tr>
<tr>
<th>Duration</th>
<td>{durationSeconds} seconds</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-5 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Result Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator</th>
<td>{creatorDetails}</td>
</tr>
<tr>
<th>Duration</th>
<td>{durationSeconds} seconds</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold"> Template Details </h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Template used</th>
<td>
<Link to={templateLink}>{templateName}</Link>
</td>
</tr>
<tr>
<th>Template creator</th>
<td>{templateCreatorDetails}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lInferenceResult?.frame_width} x{" "}
{w2lInferenceResult?.frame_height}
</td>
</tr>
</tbody>
</table>
</div>
</motion.div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold"> Template Details </h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Template used</th>
<td>
<Link to={templateLink}>{templateName}</Link>
</td>
</tr>
<tr>
<th>Template creator</th>
<td>{templateCreatorDetails}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lInferenceResult?.frame_width} x{" "}
{w2lInferenceResult?.frame_height}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</Fade>
</motion.div>
<div>{moderatorRows}</div>
<motion.div variants={panel}>{moderatorRows}</motion.div>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container pb-5">
<div className="d-flex gap-3 flex-column flex-md-row">
{editButton}
{deleteButton}
</div>
<div className="mt-4">
<ReportDiscordLinkFc />
</div>
<motion.div className="container pb-5" variants={item}>
<div className="d-flex gap-3 flex-column flex-md-row">
{editButton}
{deleteButton}
</div>
</Fade>
</div>
<motion.div className="mt-4" variants={item}>
<ReportDiscordLinkFc />
</motion.div>
</motion.div>
</motion.div>
);
}
@@ -10,8 +10,8 @@ import {
} from "../../../api/w2l/GetW2lTemplate";
import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_APPROVED_STATE = true;
@@ -118,88 +118,80 @@ function W2lTemplateApproveFc(props: Props) {
}
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">{h1Title}</h1>
</div>
<div className="pt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
{h1Title}
</motion.h1>
</div>
</Fade>
<motion.div className="pt-3" variants={item}>
<BackLink link={templateLink} text="Back to template" />
</motion.div>
</div>
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<div className="container-panel pt-4 pb-5">
<motion.div className="container-panel pt-4 pb-5" variants={panel}>
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
<thead>
<tr>
<th>
<abbr title="Detail">Detail</abbr>
</th>
<th>
<abbr title="Value">Value</abbr>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
</tbody>
</table>
</div>
</motion.div>
<motion.form onSubmit={handleApproveFormSubmit} variants={panel}>
<div className="container-panel pt-1 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
<thead>
<tr>
<th>
<abbr title="Detail">Detail</abbr>
</th>
<th>
<abbr title="Value">Value</abbr>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
</tbody>
</table>
</div>
</div>
<label className="sub-title">
Mod Approval (sets public list visibility)
</label>
<form onSubmit={handleApproveFormSubmit}>
<div className="container-panel pt-1 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<label className="sub-title">
Mod Approval (sets public list visibility)
</label>
<div>
<div className="form-group">
<select
name="approve"
value={approvedFormDefaultState}
onChange={handleModApprovalChange}
className="form-select"
>
<option value="true">Approve</option>
<option value="false">Disapprove</option>
</select>
</div>
<div>
<div className="form-group">
<select
name="approve"
value={approvedFormDefaultState}
onChange={handleModApprovalChange}
className="form-select"
>
<option value="true">Approve</option>
<option value="false">Disapprove</option>
</select>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Moderate</button>
</div>
</form>
</Fade>
</div>
</div>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Moderate</button>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -10,8 +10,8 @@ import {
} from "../../../api/w2l/GetW2lTemplate";
import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface Props {
sessionWrapper: SessionWrapper;
@@ -169,26 +169,20 @@ function W2lTemplateDeleteFc(props: Props) {
}
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">{h1Title}</h1>
</div>
<div className="pt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold" variants={item}>
{h1Title}
</motion.h1>
</div>
</Fade>
<motion.div className="pt-3" variants={item}>
<BackLink link={templateLink} text="Back to template" />
</motion.div>
</div>
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<div className="container pt-4 pb-5">
<motion.form onSubmit={handleDeleteFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
<thead>
@@ -225,16 +219,14 @@ function W2lTemplateDeleteFc(props: Props) {
</div>
</div>
<form onSubmit={handleDeleteFormSubmit}>
<div className="container">
<button className={buttonCss}>{buttonTitle}</button>
</div>
<div className="container pb-5">
<p className="pt-4">{formLabel}</p>
</div>
</form>
</Fade>
</div>
<motion.div className="container" variants={item}>
<button className={buttonCss}>{buttonTitle}</button>
</motion.div>
<motion.div className="container pb-5" variants={item}>
<p className="pt-4">{formLabel}</p>
</motion.div>
</motion.form>
</motion.div>
);
}
@@ -11,8 +11,8 @@ import {
W2lTemplate,
} from "../../../api/w2l/GetW2lTemplate";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
const DEFAULT_VISIBILITY = "public";
@@ -118,90 +118,78 @@ function W2lTemplateEditFc(props: Props) {
visibility === "public" ? <VisibleIconFc /> : <HiddenIconFc />;
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Edit Template</h1>
</div>
<div className="mt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Edit Template</h1>
</div>
</Fade>
<div className="mt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<form onSubmit={handleFormSubmit}>
<fieldset disabled={isDisabled}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Template title</label>
<div className="form-group">
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Template title"
value={title}
/>
</div>
{/*<p className="help">{invalidReason}</p>*/}
<motion.form onSubmit={handleFormSubmit} variants={panel}>
<fieldset disabled={isDisabled}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Template title</label>
<div className="form-group">
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Template title"
value={title}
/>
</div>
{/*<p className="help">{invalidReason}</p>*/}
</div>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={5}
/>
</div>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={5}
/>
</div>
</div>
<div>
<label className="sub-title">
Template Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
<div>
<label className="sub-title">
Template Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Update Template</button>
</div>
</fieldset>
</form>
</Fade>
</div>
<motion.div className="container pb-5" variants={item}>
<button className="btn btn-primary w-100">Update Template</button>
</motion.div>
</fieldset>
</motion.form>
</motion.div>
);
}
@@ -23,9 +23,8 @@ import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount"
import { BackLink } from "../../_common/BackLink";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
import { motion } from "framer-motion";
import { container, item, panel } from "../../../../data/animation";
interface EnqueueJobResponsePayload {
success: boolean;
@@ -217,55 +216,53 @@ function W2lTemplateViewFc(props: Props) {
) {
moderatorRows = (
<>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator is banned</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Create IP address</th>
<td>
{w2lTemplate?.maybe_moderator_fields
?.creator_ip_address_creation || "server error"}
</td>
</tr>
<tr>
<th>Update IP address</th>
<td>
{w2lTemplate?.maybe_moderator_fields
?.creator_ip_address_last_update || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.mod_deleted_at ||
"not deleted"}
</td>
</tr>
<tr>
<th>User deleted at (UTC)</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.user_deleted_at ||
"not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={item}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Creator is banned</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Create IP address</th>
<td>
{w2lTemplate?.maybe_moderator_fields
?.creator_ip_address_creation || "server error"}
</td>
</tr>
<tr>
<th>Update IP address</th>
<td>
{w2lTemplate?.maybe_moderator_fields
?.creator_ip_address_last_update || "server error"}
</td>
</tr>
<tr>
<th>Mod deleted at (UTC)</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.mod_deleted_at ||
"not deleted"}
</td>
</tr>
<tr>
<th>User deleted at (UTC)</th>
<td>
{w2lTemplate?.maybe_moderator_fields?.user_deleted_at ||
"not deleted"}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</Fade>
</motion.div>
</>
);
}
@@ -377,21 +374,19 @@ function W2lTemplateViewFc(props: Props) {
if (!!w2lTemplate?.description_rendered_html) {
templateDescription = (
<>
<Fade bottom duration={duration} distance={distance} delay={delay}>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Description</h2>
<div className="py-6">
<div
className="profile content is-medium"
dangerouslySetInnerHTML={{
__html: w2lTemplate?.description_rendered_html || "",
}}
/>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Model Description</h2>
<div className="py-6">
<div
className="profile content is-medium"
dangerouslySetInnerHTML={{
__html: w2lTemplate?.description_rendered_html || "",
}}
/>
</div>
</div>
</Fade>
</motion.div>
</>
);
}
@@ -408,156 +403,146 @@ function W2lTemplateViewFc(props: Props) {
);
return (
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold">Video Lip Sync Template</h1>
<h4>Template: {w2lTemplate?.title}</h4>
<div className="pt-3">
<BackLink
link={FrontendUrlConfig.w2lListPage()}
text="Back to all templates"
/>
</div>
</div>
</Fade>
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<motion.h1 className="display-5 fw-bold" variants={item}>
Video Lip Sync Template
</motion.h1>
<motion.h4 variants={item}>Template: {w2lTemplate?.title}</motion.h4>
<motion.div className="pt-3" variants={item}>
<BackLink
link={FrontendUrlConfig.w2lListPage()}
text="Back to all templates"
/>
</motion.div>
</div>
<Fade
bottom
cascade
duration={duration}
distance={distance}
delay={delay}
>
<form onSubmit={handleInferenceFormSubmit}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Upload Audio</h2>
<div className="py-6">
<div className="d-flex flex-column flex-lg-row gap-5">
<div className="d-flex flex-column gap-4 w-100 w-lg-50">
<p>
Upload audio from FakeYou or any other source (eg. music),
then submit. You'll get a beautifully lipsynced video.
</p>
<div>
<label className="sub-title">Select an audio file</label>
<input
id="formFileLg"
type="file"
name="audio"
className="form-control form-control-lg"
onChange={(e) => handleAudioFileChange(e.target.files)}
/>
</div>
<button className="btn btn-primary w-100 mt-3">
Submit
</button>
<motion.form onSubmit={handleInferenceFormSubmit} variants={panel}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Upload Audio</h2>
<div className="py-6">
<div className="d-flex flex-column flex-lg-row gap-5">
<div className="d-flex flex-column gap-4 w-100 w-lg-50">
<p>
Upload audio from FakeYou or any other source (eg. music),
then submit. You'll get a beautifully lipsynced video.
</p>
<div>
<label className="sub-title">Select an audio file</label>
<input
id="formFileLg"
type="file"
name="audio"
className="form-control form-control-lg"
onChange={(e) => handleAudioFileChange(e.target.files)}
/>
</div>
<div className="d-flex w-100 w-lg-50 justify-content-center">
<div className="template-preview ">
<img
src={url}
alt="template preview"
className="img-fluid rounded"
/>
</div>
<button className="btn btn-primary w-100 mt-3">Submit</button>
</div>
<div className="d-flex w-100 w-lg-50 justify-content-center">
<div className="template-preview ">
<img
src={url}
alt="template preview"
className="img-fluid rounded"
/>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</motion.form>
<div>{templateDescription}</div>
<motion.div variants={panel}>{templateDescription}</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Template Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>Is public listing approved?</th>
<td>{modApprovalStatus}</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Template Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>Is public listing approved?</th>
<td>{modApprovalStatus}</td>
</tr>
</tbody>
</table>
</div>
</div>
</motion.div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Media Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Media type</th>
<td>{w2lTemplate?.template_type}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lTemplate?.frame_width} x {w2lTemplate?.frame_height}
</td>
</tr>
<tr>
<th>Duration (milliseconds)</th>
<td>{w2lTemplate?.duration_millis}</td>
</tr>
<tr>
<th>Created at (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
<tr>
<th>Updated at (UTC)</th>
<td>{w2lTemplate?.updated_at}</td>
</tr>
</tbody>
</table>
</div>
<motion.div className="container-panel pt-3 pb-5" variants={panel}>
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Media Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Media type</th>
<td>{w2lTemplate?.template_type}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lTemplate?.frame_width} x {w2lTemplate?.frame_height}
</td>
</tr>
<tr>
<th>Duration (milliseconds)</th>
<td>{w2lTemplate?.duration_millis}</td>
</tr>
<tr>
<th>Created at (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
<tr>
<th>Updated at (UTC)</th>
<td>{w2lTemplate?.updated_at}</td>
</tr>
</tbody>
</table>
</div>
</div>
</motion.div>
<div>{moderatorRows}</div>
<motion.div variants={panel}>{moderatorRows}</motion.div>
<div className="container">
<div className="d-flex flex-column flex-lg-row gap-3">
{editButton}
{approveButton}
{deleteButton}
</div>
<motion.div className="container" variants={item}>
<div className="d-flex flex-column flex-lg-row gap-3">
{editButton}
{approveButton}
{deleteButton}
</div>
</motion.div>
<div>
<div className="container pt-4 pb-5">
<ReportDiscordLinkFc />
</div>
<motion.div variants={item}>
<div className="container pt-4 pb-5">
<ReportDiscordLinkFc />
</div>
</Fade>
</motion.div>
<SessionW2lInferenceResultListFc
w2lInferenceJobs={props.w2lInferenceJobs}
/>
</div>
</motion.div>
);
}