Merge pull request #42 from storytold/bflat-main-tts-page

main TTS page styling fixes
This commit is contained in:
Brandon Thomas authored and GitHub committed 2022-07-23 19:27:04 -04:00
commit fad28a1cd2
11 files changed
+322 -196

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
BROWSER=none
HTTPS=true
+2 -2
View File
@@ -147,10 +147,10 @@ $headings-font-family: "Merriweather", serif;
font-size: 15px;
font-weight: 600;
padding: 0.5rem 1rem;
color: #212529;
color: $secondary;
&:hover {
color: #212529;
color: $secondary;
}
&:focus {
background-color: $white;
+2 -1
View File
@@ -1,4 +1,5 @@
$primary: #fc6b68;
$secondary: #212529;
$info: #252d43;
$success: #40ad48;
$danger: #e51c23;
@@ -47,4 +48,4 @@ $danger-light: desaturate(lighten($danger, 15%), 15%);
$danger-dark: darken($danger, 10%);
$accent-light: desaturate(lighten($accent, 20%), 15%);
$accent-dark: saturate(darken($accent, 15%), 10%);
$accent-dark: saturate(darken($accent, 15%), 10%);
+45 -3
View File
@@ -148,14 +148,14 @@ styles with important tags:
.btn-secondary:focus,
.btn-secondary:active {
background-color: $white;
color: #212529;
color: $secondary;
border: 2.5px solid;
border-color: $white;
transition: 0.2s;
}
.btn-secondary:hover {
background-color: #ccc;
color: #212529;
color: $secondary;
border: 2.5px solid;
border-color: #ccc;
}
@@ -177,6 +177,14 @@ styles with important tags:
border-color: #fdcfce;
}
.btn-inform {
height: 42px;
align-items: center;
padding: 0 0.75rem;
padding-top: 1px;
font-size: 22px;
}
.panel {
position: relative;
width: 100%;
@@ -214,6 +222,26 @@ styles with important tags:
}
}
.menu {
border-radius: 8px !important;
color: #000;
font-weight: 400;
position: absolute;
border-color: rgba($white, 0.12) !important;
border: 1px solid;
border-radius: 8px;
box-shadow: 0px 5px 20px rgba($black, 0.3);
z-index: 3;
overflow: hidden;
}
.menu-item {
padding: 0.25rem;
padding-left: 2.375rem;
padding-right: 2.375rem;
cursor: pointer;
}
.login-panel {
max-width: 800px !important;
backdrop-filter: blur(5px);
@@ -279,7 +307,7 @@ styles with important tags:
// line-height: 2.69rem;
text-align: center;
pointer-events: none;
color: #212529;
color: $secondary;
opacity: 0.9;
}
}
@@ -459,6 +487,20 @@ styles with important tags:
color: #664d03;
}
}
.alert {
.close {
position: absolute;
border-radius: 50px;
border: none;
background: none;
padding: 0;
margin: 0;
right: 12px;
top: 0px;
font-size: 30px;
}
}
}
@media (min-width: 992px) {
@@ -38,51 +38,59 @@ export function AutocompleteSearch(props: Props) {
return (
<>
<div className="field">
<strong style={{ display: "block", margin: "7px 0 0 0"}}>{t('ttsListPage.search')}</strong>
<strong style={{ display: "block", margin: "7px 0 0 0" }}>
{t("ttsListPage.search")}
</strong>
<div className="control has-icons-left">
{/* NB: See note above about this library. */}
<Autocomplete
getItemValue={(item : TtsModelListItem) => item.title}
getItemValue={(item: TtsModelListItem) => item.title}
items={props.allTtsModels}
renderInput={(props) => (
<input
className="input"
type="text"
placeholder={t('ttsListPage.searchTerm')}
value={searchValue} {...props} />
<input
className="input"
type="text"
placeholder={t("ttsListPage.searchTerm")}
value={searchValue}
{...props}
/>
)}
renderMenu={children => (
<div className="menu">
{children.slice(0, maxMenuItems)}
</div>
renderMenu={(children) => (
<div className="menu">{children.slice(0, maxMenuItems)}</div>
)}
renderItem={(item : TtsModelListItem, isHighlighted : boolean) =>
<div style={{ background: isHighlighted ? 'lightgray' : 'white' }}>
renderItem={(item: TtsModelListItem, isHighlighted: boolean) => (
<div
style={{ background: isHighlighted ? "lightgray" : "white" }}
>
{item.title}
</div>
}
)}
value={searchValue}
onChange={(e : any) => setSearchValue(e.target.value) }
onSelect={(val : string, item: TtsModelListItem) => {
onChange={(e: any) => setSearchValue(e.target.value)}
onSelect={(val: string, item: TtsModelListItem) => {
// Nothing selected.
props.setSelectedCategories([]);
// And the dropdowns themselves
// Shouldn't need to rebuild this...
let newDropdownCategories = props.dropdownCategories.slice(0, 1);
let newDropdownCategories = props.dropdownCategories.slice(
0,
1
);
if (newDropdownCategories.length === 0) {
// ...but just in case.
newDropdownCategories.push(props.allTtsCategories.filter(category => {
return category.maybe_super_category_token === undefined;
}));
newDropdownCategories.push(
props.allTtsCategories.filter((category) => {
return category.maybe_super_category_token === undefined;
})
);
}
props.setDropdownCategories(newDropdownCategories);
props.setMaybeSelectedTtsModel(item)
props.setMaybeSelectedTtsModel(item);
}}
shouldItemRender={(item : TtsModelListItem, value) => {
shouldItemRender={(item: TtsModelListItem, value) => {
// TODO: A trie would be so much better. Ugh, this is so bad.
let test = value.toLocaleLowerCase().trim();
if (test.length === 0) {
@@ -90,9 +98,13 @@ export function AutocompleteSearch(props: Props) {
}
return item.title.toLocaleLowerCase().includes(test);
}}
inputProps={{ id: 'states-autocomplete' }}
wrapperStyle={{ position: 'relative', display: 'inline-block' }}
inputProps={{
id: "states-autocomplete",
}}
wrapperStyle={{
position: "relative",
display: "inline-block",
}}
/>
<span className="icon is-small is-left">
<FontAwesomeIcon icon={faSearch} />
@@ -112,6 +124,7 @@ export function AutocompleteSearch(props: Props) {
<span className="form-control-feedback">
<FontAwesomeIcon icon={faSearch} />
</span>
<Autocomplete
getItemValue={(item: TtsModelListItem) => item.title}
items={props.allTtsModels}
@@ -125,10 +138,13 @@ export function AutocompleteSearch(props: Props) {
/>
)}
renderMenu={(children) => (
<div className="menu">{children.slice(0, maxMenuItems)}</div>
<div className="menu w-100">
{children.slice(0, maxMenuItems)}
</div>
)}
renderItem={(item: TtsModelListItem, isHighlighted: boolean) => (
<div
className="menu-item"
style={{ background: isHighlighted ? "lightgray" : "white" }}
>
{item.title}
@@ -165,7 +181,11 @@ export function AutocompleteSearch(props: Props) {
return item.title.toLocaleLowerCase().includes(test);
}}
inputProps={{ id: "states-autocomplete" }}
wrapperStyle={{ position: "relative", display: "inline-block" }}
wrapperStyle={{
position: "relative",
display: "inline-block",
width: "100%",
}}
/>
</div>
</div>
@@ -1,6 +1,7 @@
import React, { useEffect } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCaretRight,
faChevronRight,
faHeadphonesAlt,
faMicrophone,
@@ -201,14 +202,14 @@ export function MultiDropdownSearch(props: Props) {
if (USE_REFRESH) {
// Redesign and Bootstrap CSS
selectCssClasses = "category-dropdown form-select"; // NB: 'category-dropdown' is important for function.
selectCssClasses = "category-dropdown form-select"; // NB: 'category-dropdown' is important for function.
xButtonCssClasses = "btn btn-destructive btn-inform";
}
categoryDropdowns.push(
<React.Fragment key={`categoryDropdown-${i}`}>
<div className="control has-icons-left is-expanded">
<div className="select is-fullwidth">
<div className="d-flex gap-3 align-items-center mb-4 w-100">
<div className="form-group input-icon w-100">
<select
className={selectCssClasses}
name={`categories-${i}`}
@@ -217,25 +218,29 @@ export function MultiDropdownSearch(props: Props) {
>
{dropdownOptions}
</select>
</div>
<span className="icon is-small is-left">
<FontAwesomeIcon icon={faTags} />
</span>
</div>
<div className="control">
<button
className={xButtonCssClasses}
onClick={() => handleRemoveCategory(i)}
>
<span className="icon is-normal">
<FontAwesomeIcon icon={faTimes} title="remove" color="#f14668" />
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
</button>
</div>
</div>
<div className="control">
<FontAwesomeIcon icon={faChevronRight} size="2x" color="#999" />
<div>
<button
className={xButtonCssClasses}
onClick={() => handleRemoveCategory(i)}
>
<span className="icon is-normal">
<FontAwesomeIcon
icon={faTimes}
title="remove"
color="#f14668"
/>
</span>
</button>
</div>
<div className="control">
<FontAwesomeIcon icon={faCaretRight} size="2x" color="#999" />
</div>
</div>
</React.Fragment>
);
@@ -251,7 +256,10 @@ export function MultiDropdownSearch(props: Props) {
if (categoryFields.length >= groupSize) {
categoryFieldGroups.push(
<div className="field is-grouped is-grouped" key={`fieldGroup-${i}`}>
<div
className="d-flex gap-0 flex-column flex-lg-row gap-lg-3"
key={`fieldGroup-${i}`}
>
{categoryFields.splice(0, categoryFields.length)}
</div>
);
@@ -260,7 +268,7 @@ export function MultiDropdownSearch(props: Props) {
if (categoryFields.length >= 0) {
categoryFieldGroups.push(
<div className="field is-grouped is-grouped" key="fieldGroup-last">
<div className="d-flex" key="fieldGroup-last">
{categoryFields.splice(0, categoryFields.length)}
</div>
);
@@ -295,32 +303,34 @@ export function MultiDropdownSearch(props: Props) {
return (
<div>
{/* Category Dropdowns */}
<strong>{t('ttsListPage.categoryFilters')}</strong>
<strong>{t("ttsListPage.categoryFilters")}</strong>
<br />
{categoryFieldGroups}
{/* Model Dropdown */}
<strong>
<Trans i18nKey="ttsListPage.voiceCount" count={voiceCount}>
Voice ({voiceCount} to choose from)
Voice ({voiceCount} to choose from)
</Trans>
</strong>
<br />
<div className="control has-icons-left">
<div className={selectClasses}>
<select
name="tts-model-select"
onChange={handleChangeVoice}
disabled={isLoading}
>
{isLoading ? loadingOption : Array.from(leafiestCategoryModels).map(model => {
return (
<option
key={model.model_token}
value={model.model_token}
>{model.title} ({t('ttsListPage.by')} {model.creator_display_name})</option>
);
})}
<select
name="tts-model-select"
onChange={handleChangeVoice}
disabled={isLoading}
>
{isLoading
? loadingOption
: Array.from(leafiestCategoryModels).map((model) => {
return (
<option key={model.model_token} value={model.model_token}>
{model.title} ({t("ttsListPage.by")}{" "}
{model.creator_display_name})
</option>
);
})}
</select>
</div>
<span className="icon is-small is-left">
@@ -328,14 +338,13 @@ export function MultiDropdownSearch(props: Props) {
</span>
</div>
</div>
)
);
}
return (
<div>
{/* Category Dropdowns */}
<label className="sub-title">{t("ttsListPage.categoryFilters")}</label>
<br />
{categoryFieldGroups}
{/* Model Dropdown */}
@@ -38,7 +38,11 @@ import { TwitchTtsNotice } from "./notices/TwitchTtsNotice";
import { PleaseFollowNotice } from "./notices/PleaseFollowNotice";
import { distance, delay, delay2, duration } from "../../../../data/animation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faVolumeUp } from "@fortawesome/free-solid-svg-icons";
import {
faTrash,
faVolumeHigh,
faVolumeUp,
} from "@fortawesome/free-solid-svg-icons";
import { USE_REFRESH } from "../../../../Refresh";
const Fade = require("react-reveal/Fade");
@@ -208,10 +212,11 @@ function TtsModelListFc(props: Props) {
let modelName = props.maybeSelectedTtsModel.title;
let userName = props.maybeSelectedTtsModel.creator_display_name;
directViewLink = (
<Link to={modelLink}>
<Link to={modelLink} className="py-2">
<Trans i18nKey="ttsListPage.seeModelDetails">
See more details about the "<strong>{{ modelName }}</strong>" model
by&nbsp;<strong>{{ userName }}</strong>&nbsp;
See more details about the "
<span className="fw-semibold">{{ modelName }}</span>" model by&nbsp;
<span className="fw-semibold">{{ userName }}</span>&nbsp;
</Trans>
<Gravatar
size={15}
@@ -267,11 +272,10 @@ function TtsModelListFc(props: Props) {
if (hasMessage) {
maybeError = (
<div className="notification is-warning">
<button
className="delete"
onClick={() => setMaybeTtsError(undefined)}
></button>
<div className="alert alert-warning m-0">
<button className="close" onClick={() => setMaybeTtsError(undefined)}>
<span aria-hidden="true">&times;</span>
</button>
{message}
</div>
);
@@ -343,10 +347,7 @@ function TtsModelListFc(props: Props) {
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
/>
{directViewLink}
<br />
<br />
<div>{directViewLink}</div>
<div className="field">
<div className="control">
@@ -470,7 +471,7 @@ function TtsModelListFc(props: Props) {
{twitchTtsNotice}
<div className="container-panel pt-4 pb-5">
<div className="container-panel pt-4 pb-5 mb-4">
<Fade bottom distance={distance} delay={delay2} duration={duration}>
<div className="panel p-3 p-lg-4 mt-5 mt-lg-0">
<i className="fas fa-volume-high"></i>
@@ -531,12 +532,14 @@ function TtsModelListFc(props: Props) {
className="btn btn-primary w-100"
disabled={remainingCharactersButtonDisabled}
>
<FontAwesomeIcon icon={faVolumeHigh} className="me-2" />
{t("pages.ttsList.buttonSpeak")}
</button>
<button
className="btn btn-destructive w-100"
onClick={handleClearClick}
>
<FontAwesomeIcon icon={faTrash} className="me-2" />
{t("pages.ttsList.buttonClear")}
</button>
</div>
@@ -547,31 +550,22 @@ function TtsModelListFc(props: Props) {
</Fade>
</div>
<br />
<br />
<SessionTtsInferenceResultListFc
ttsInferenceJobs={props.ttsInferenceJobs}
/>
<br />
<br />
<SessionW2lInferenceResultListFc
w2lInferenceJobs={props.w2lInferenceJobs}
/>
<br />
<br />
<SessionW2lTemplateUploadResultListFc
w2lTemplateUploadJobs={props.w2lTemplateUploadJobs}
/>
<br />
<br />
<SessionTtsModelUploadResultListFc
modelUploadJobs={props.ttsModelUploadJobs}
/>
<br />
</div>
);
}
@@ -1,10 +1,10 @@
import React from 'react';
import { Language } from '@storyteller/components/src/i18n/Language';
import { DiscordLink } from '@storyteller/components/src/elements/DiscordLink';
import React from "react";
import { Language } from "@storyteller/components/src/i18n/Language";
import { DiscordLink } from "@storyteller/components/src/elements/DiscordLink";
interface Props {
clearLanguageNotice: () => void,
displayLanguage: Language,
clearLanguageNotice: () => void;
displayLanguage: Language;
}
/* Template:
@@ -18,55 +18,80 @@ interface Props {
We will pay for the first fifty {LANGUAGE} models uploaded.
*/
function LanguageNotice (props: Props) {
function LanguageNotice(props: Props) {
let title = "¡Bienvenidos!";
let weHaveModels = (<>
<p>Tenemos modelos de habla hispana. Echa un vistazo a la categoría "Español"
("Category Filters").</p>
</>);
let joinUs = (<>
<p>
Podemos ayudarte a hacer tus propias voces.&nbsp;
<DiscordLink text="Únete a nuestro chat Discord" iconAfterText={true} />.
Pagaremos por los primeros cincuenta modelos subidos.
</p>
</>);
let weHaveModels = (
<>
<p>
Tenemos modelos de habla hispana. Echa un vistazo a la categoría
"Español" ("Category Filters").
</p>
</>
);
let joinUs = (
<>
<p>
Podemos ayudarte a hacer tus propias voces.&nbsp;
<DiscordLink text="Únete a nuestro chat Discord" iconAfterText={true} />
. Pagaremos por los primeros cincuenta modelos subidos.
</p>
</>
);
if (props.displayLanguage === Language.Portuguese) {
title = "Bem vinda!";
weHaveModels = (<>
<p>Temos modelos que falam português. Dê uma olhada na categoria "Português" ("Filtros de Categoria").</p>
</>);
joinUs = (<>
<p>
Nós podemos ajudá-lo a fazer suas próprias vozes.&nbsp;
<DiscordLink text="Participe do nosso bate-papo no Discord" iconAfterText={true} />.
Pagaremos os primeiros cinquenta modelos portugueses carregados.
</p>
</>);
weHaveModels = (
<>
<p>
Temos modelos que falam português. Dê uma olhada na categoria
"Português" ("Filtros de Categoria").
</p>
</>
);
joinUs = (
<>
<p>
Nós podemos ajudá-lo a fazer suas próprias vozes.&nbsp;
<DiscordLink
text="Participe do nosso bate-papo no Discord"
iconAfterText={true}
/>
. Pagaremos os primeiros cinquenta modelos portugueses carregados.
</p>
</>
);
} else if (props.displayLanguage === Language.Turkish) {
title = "Hoş geldin!";
weHaveModels = <></>;
joinUs = (<>
<p>
Kendi sesinizi çıkarmanıza yardımcı olabiliriz.&nbsp;
<DiscordLink text="Discord sohbetimize katılın" iconAfterText={true} />.
Yüklenen ilk elli Türk modelinin ücretini biz ödeyeceğiz.
</p>
</>);
joinUs = (
<>
<p>
Kendi sesinizi çıkarmanıza yardımcı olabiliriz.&nbsp;
<DiscordLink
text="Discord sohbetimize katılın"
iconAfterText={true}
/>
. Yüklenen ilk elli Türk modelinin ücretini biz ödeyeceğiz.
</p>
</>
);
}
return (
<>
<div className="notification is-link">
<button className="delete" onClick={() => props.clearLanguageNotice()}></button>
<h1>{title}</h1>
{weHaveModels}
{joinUs}
\
<div className="container pb-5">
<div className="alert alert-primary alert-dismissible position-relative">
<button className="close" onClick={() => props.clearLanguageNotice()}>
<span aria-hidden="true">&times;</span>
</button>
<h1>{title}</h1>
{weHaveModels}
{joinUs}
</div>
</div>
</>
)
);
}
export { LanguageNotice }
export { LanguageNotice };
@@ -1,44 +1,48 @@
import { DiscordLink2 } from '@storyteller/components/src/elements/DiscordLink2';
import { Trans } from 'react-i18next';
import { TwitterLink } from '@storyteller/components/src/elements/TwitterLink';
import { TwitchLabsLink } from '@storyteller/components/src/elements/TwitchLabsLink';
import React from 'react';
import { DiscordLink2 } from "@storyteller/components/src/elements/DiscordLink2";
import { Trans } from "react-i18next";
import { TwitterLink } from "@storyteller/components/src/elements/TwitterLink";
import { TwitchLabsLink } from "@storyteller/components/src/elements/TwitchLabsLink";
import React from "react";
interface Props {
clearPleaseFollowNotice: () => void,
clearPleaseFollowNotice: () => void;
}
function PleaseFollowNotice(props: Props) {
return (
<>
<div className="notification is-warning">
<button className="delete" onClick={() => props.clearPleaseFollowNotice()}></button>
<p>
<div className="container pb-5">
<div className="alert alert-primary alert-dismissible position-relative">
<button
className="close"
onClick={() => props.clearPleaseFollowNotice()}
>
<span aria-hidden="true">&times;</span>
</button>
<strong>
<Trans i18nKey="notices.pleaseFollow.title">
Sorry our site is so slow!
Sorry our site is so slow!
</Trans>
</strong>
</p>
<br />
<p>
<br />
<Trans i18nKey="notices.pleaseFollow.body">
I am so sorry the website is slow. We're getting millions of
requests. <TwitterLink>Please follow us on Twitter</TwitterLink> and
also <DiscordLink2>join our Discord</DiscordLink2>.
I'm going to introduce faster processing (less than one minute) for those that
follow us and help support our work. So please follow our Twitter and join our Discord.
Our new <TwitchLabsLink>video deepfake technology will debut on Twitch</TwitchLabsLink>,
so please follow us there too.
I am so sorry the website is slow. We're getting millions of
requests. <TwitterLink>Please follow us on Twitter</TwitterLink> and
also <DiscordLink2>join our Discord</DiscordLink2>. I'm going to
introduce faster processing (less than one minute) for those that
follow us and help support our work. So please follow our Twitter
and join our Discord. Our new{" "}
<TwitchLabsLink>
video deepfake technology will debut on Twitch
</TwitchLabsLink>
, so please follow us there too.
</Trans>
</p>
<br />
<p>
<br />
<DiscordLink2 /> | <TwitterLink /> | <TwitchLabsLink />
</p>
</div>
</div>
</>
)
);
}
export { PleaseFollowNotice }
export { PleaseFollowNotice };
@@ -1,30 +1,50 @@
import React from 'react';
import React from "react";
interface Props {
clearTwitchTtsNotice: () => void,
clearTwitchTtsNotice: () => void;
}
function TwitchTtsNotice(props: Props) {
return (
<>
<div className="notification is-warning">
<button className="delete" onClick={() => props.clearTwitchTtsNotice()}></button>
<p>
<strong>If you stream on Twitch, we have a brand new platform for you!</strong>
</p>
<br />
<p>
Allow us to introduce <a href="https://create.storyteller.io" target="_blank" rel="noreferrer"><strong>Storyteller</strong></a>,
a free, zero-download, easy to use platform that lets you use
FakeYou voices on your Twitch stream. Your audience can use bits, channel points,
and soon much more. We've got a ton of features in store. <a href="https://create.storyteller.io" target="_blank" rel="noreferrer">Try it out and
let us know what you think!</a>
</p>
<br />
<p>You think voices are neat? Just wait until we show you what else we've been working on&hellip;</p>
<div className="container pb-5">
<div className="alert alert-primary alert-dismissible position-relative">
<button
className="close"
onClick={() => props.clearTwitchTtsNotice()}
>
<span aria-hidden="true">&times;</span>
</button>
<strong>
If you stream on Twitch, we have a brand new platform for you!
</strong>
<br />
Allow us to introduce{" "}
<a
href="https://create.storyteller.io"
target="_blank"
rel="noreferrer"
>
<strong>Storyteller</strong>
</a>
, a free, zero-download, easy to use platform that lets you use
FakeYou voices on your Twitch stream. Your audience can use bits,
channel points, and soon much more. We've got a ton of features in
store.{" "}
<a
href="https://create.storyteller.io"
target="_blank"
rel="noreferrer"
>
Try it out and let us know what you think!
</a>
<br />
You think voices are neat? Just wait until we show you what else we've
been working on&hellip;
</div>
</div>
</>
)
);
}
export { TwitchTtsNotice }
export { TwitchTtsNotice };
@@ -1,7 +1,7 @@
import React from 'react';
import React from "react";
interface Props {
clearVocodesNotice: () => void,
clearVocodesNotice: () => void;
}
function VocodesNotice(props: Props) {
@@ -16,17 +16,26 @@ function VocodesNotice(props: Props) {
production and deepfake tools, so stay tuned.
</div>
</article>*/}
<div className="notification is-link">
<button className="delete" onClick={() => props.clearVocodesNotice()}></button>
<p><em>Vocodes</em> is now <strong><em>FakeYou</em></strong>!
Why the change? Not many know what vocoders are, so the old name was kind of silly.
We've also got lots of ambitious plans for the future, including a full set of virtual
production and deepfake tools, so stay tuned.</p>
<br />
<p>(You can access us at <a href="https://fakeyou.com">FakeYou.com</a> to get rid of this notice forever.)</p>
<div className="container pb-5">
<div className="alert alert-primary alert-dismissible position-relative">
<button className="close" onClick={() => props.clearVocodesNotice()}>
<span aria-hidden="true">&times;</span>
</button>
<em>Vocodes</em> is now{" "}
<strong>
<em>FakeYou</em>
</strong>
! Why the change? Not many know what vocoders are, so the old name was
kind of silly. We've also got lots of ambitious plans for the future,
including a full set of virtual production and deepfake tools, so stay
tuned.
<br />
(You can access us at <a href="https://fakeyou.com">FakeYou.com</a> to
get rid of this notice forever.)
</div>
</div>
</>
)
);
}
export { VocodesNotice }
export { VocodesNotice };