main tts page design updates

This commit is contained in:
BFlat authored and Brandon Thomas committed 2023-01-18 04:53:34 -05:00
1 parent 48c0f64898
commit 7663f00c84
7 files changed
+917 -169

No files matched your search

+1
View File
@@ -28,6 +28,7 @@
"lerna": "^4.0.0"
},
"dependencies": {
"react-select": "^5.7.0",
"yarn": "^1.22.19"
}
}
@@ -41,6 +41,7 @@ styles with important tags:
select {
cursor: pointer;
border-radius: 5px;
}
.no-wrap {
@@ -81,6 +82,10 @@ styles with important tags:
border-radius: 8px !important;
}
.rounded-5 {
border-radius: 5px !important;
}
code {
color: $primary;
background-color: rgba($white, 0.06);
@@ -143,7 +148,7 @@ styles with important tags:
.alert-cta {
font-weight: 500 !important;
font-size: 18px !important;
font-size: 16px !important;
}
.btn {
@@ -220,6 +225,7 @@ styles with important tags:
padding: 0 0.75rem;
padding-top: 1px;
font-size: 22px;
border-radius: 50px;
}
.panel {
@@ -230,6 +236,10 @@ styles with important tags:
border: 1px solid;
border-radius: 0px;
.panel-inner {
background-color: lighten($panel, 2%);
}
.panel-title {
position: static;
text-align: center;
@@ -296,14 +306,22 @@ styles with important tags:
.form-select {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M2 5l6 6 6-6'/%3e%3c/svg%3e") !important;
border-radius: 50px;
&.main-select {
height: 48px;
}
}
.form-control {
border-radius: 5px;
}
.form-control,
.form-select {
border-width: 1px;
border-color: $white;
border-radius: 5px;
padding: 0.5rem 0.75rem;
padding: 11px 0.75rem;
&:focus {
border-color: $primary;
@@ -600,12 +618,38 @@ styles with important tags:
.btn-close {
transition: 0.2s;
}
.session-tts-section {
height: 450px;
overflow-x: hidden;
overflow-y: auto;
}
.direct-view-link {
background-color: lighten($panel, 2%);
border: 1px solid #39394c;
border-radius: 5px;
padding: 11px 16px;
&:hover {
border-color: lighten(#39394c, 10%);
}
}
}
select {
border-color: $input-dark !important;
background-color: $input-dark !important;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-chevron-down' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
transition: 0.1s !important;
&:hover {
background-color: lighten($input-dark, 5%) !important;
}
option {
background-color: $input-dark !important;
}
}
.btn-destructive {
@@ -621,10 +665,16 @@ textarea {
background-color: $input-dark !important;
border-color: $input-dark !important;
color: $white !important;
&.text-message {
font-size: 18px;
min-height: 200px !important;
}
}
.form-select {
color: $white !important;
border-radius: 50%;
}
.form-control::placeholder {
@@ -7,7 +7,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faClock,
faLink,
faList,
faHeadphonesSimple,
faMicrophone,
} from "@fortawesome/free-solid-svg-icons";
import { motion } from "framer-motion";
@@ -25,7 +25,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
props.ttsInferenceJobs.forEach((job) => {
if (!job.maybeResultToken) {
let cssStyle = "alert alert-secondary mx-3 mx-md-0";
let cssStyle = "alert alert-secondary mx-3 mx-md-0 mb-0";
let stateDescription = "Pending...";
switch (job.jobState) {
@@ -37,24 +37,24 @@ function SessionTtsInferenceResultListFc(props: Props) {
: job.maybeExtraStatusDescription;
break;
case JobState.STARTED:
cssStyle = "alert alert-success mx-3 mx-md-0";
cssStyle = "alert alert-success mx-3 mx-md-0 mb-0";
stateDescription =
job.maybeExtraStatusDescription == null
? "Started..."
: job.maybeExtraStatusDescription;
break;
case JobState.ATTEMPT_FAILED:
cssStyle = "alert alert-danger mx-3 mx-md-0";
cssStyle = "alert alert-danger mx-3 mx-md-0 mb-0";
stateDescription = `Failed ${job.attemptCount} attempt(s). Will retry...`;
break;
case JobState.COMPLETE_FAILURE:
case JobState.DEAD:
cssStyle = "alert alert-danger mx-3 mx-md-0";
cssStyle = "alert alert-danger mx-3 mx-md-0 mb-0";
stateDescription =
"Failed Permanently. Please tell us in Discord so we can fix. :(";
break;
case JobState.COMPLETE_SUCCESS:
cssStyle = "message is-success mx-3 mx-md-0";
cssStyle = "message is-success mx-3 mx-md-0 mb-0";
stateDescription = "Success!"; // Not sure why we're here instead of other branch!
break;
}
@@ -83,35 +83,36 @@ function SessionTtsInferenceResultListFc(props: Props) {
</div>*/}
<div>
<motion.div
className="panel py-4 p-3 p-lg-4 gap-4 d-flex flex-column"
className="panel panel-inner p-4 gap-3 d-flex flex-column"
variants={sessionItem}
>
<div>
<h4>
<FontAwesomeIcon icon={faMicrophone} className="me-3" />
{job.title}
</h4>
<h5 className="mb-1">{job.title}</h5>
<p>{job.rawInferenceText}</p>
</div>
<audio
className="w-100"
controls
<audio
className="w-100"
controls
src={audioLink}
onClick={() => { Analytics.ttsClickResultInlinePlay() }}
onClick={() => {
Analytics.ttsClickResultInlinePlay();
}}
>
Your browser does not support the
<code>audio</code> element.
</audio>
<div>
<Link
to={ttsPermalink}
onClick={() => { Analytics.ttsClickResultLink() }}
className="btn btn-primary"
>
<Link
to={ttsPermalink}
onClick={() => {
Analytics.ttsClickResultLink();
}}
className="fw-semibold"
>
<FontAwesomeIcon icon={faLink} className="me-2" />
Permalink &amp; download
Permalink / Download
</Link>
</div>
</motion.div>
@@ -121,18 +122,18 @@ function SessionTtsInferenceResultListFc(props: Props) {
}
});
if (results.length === 0) {
return <span />;
}
let noResultsSection = (
<div className="panel panel-inner text-center p-5 rounded-5 h-100">
<div className="d-flex flex-column opacity-75 h-100 justify-content-center">
<FontAwesomeIcon icon={faHeadphonesSimple} className="fs-3 mb-3" />
<h5 className="fw-semibold">No results yet</h5>
<p>Generated audio will appear here.</p>
</div>
</div>
);
let title = <span />;
if (results.length !== 0) {
title = (
<motion.h2 className="text-center text-lg-start fw-bold" variants={item}>
<FontAwesomeIcon icon={faList} className="me-3" />
Session TTS Results
</motion.h2>
);
if (results.length === 0) {
return <>{noResultsSection}</>;
}
let upgradeNotice = <></>;
@@ -143,18 +144,20 @@ function SessionTtsInferenceResultListFc(props: Props) {
!props.sessionSubscriptionsWrapper.hasPaidFeatures()
) {
upgradeNotice = (
<div className="d-flex flex-column gap-4 mx-3 mx-md-0">
<div className="d-flex flex-column gap-3 mx-3 mx-md-0 sticky-top">
<motion.div
className="alert alert-warning alert-cta"
className="alert alert-warning alert-cta mb-0"
variants={sessionItem}
>
<FontAwesomeIcon icon={faClock} className="me-3" />
<FontAwesomeIcon icon={faClock} className="me-2" />
Don't want to wait? Step to the front of the line with a{" "}
<Link
to="/pricing"
onClick={() => { Analytics.ttsTooSlowUpgradePremium() }}
className="alert-link"
>
<Link
to="/pricing"
onClick={() => {
Analytics.ttsTooSlowUpgradePremium();
}}
className="alert-link"
>
<span className="fw-semibold">FakeYou membership</span>.
</Link>
</motion.div>
@@ -167,12 +170,10 @@ function SessionTtsInferenceResultListFc(props: Props) {
return (
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container-panel mb-5">
<div className="d-flex flex-column gap-4">
{title}
<div>
<div className="d-flex flex-column gap-3">
{upgradeNotice}
<div className="d-flex flex-column gap-4">{results}</div>
<div className="d-flex flex-column gap-3">{results}</div>
</div>
</div>
</motion.div>
@@ -203,7 +203,9 @@ export function MultiDropdownSearch(props: Props) {
<div className="d-flex gap-3 align-items-center mb-4 w-100">
<div className="form-group input-icon w-100">
<select
onClick={() => { Analytics.ttsClickSelectCategory() } }
onClick={() => {
Analytics.ttsClickSelectCategory();
}}
className={selectCssClasses}
name={`categories-${i}`}
onChange={(ev) => handleChangeCategory(ev, i)}
@@ -295,10 +297,10 @@ export function MultiDropdownSearch(props: Props) {
return (
<div>
{/* Category Dropdowns */}
<label className="sub-title">
{/* <label className="sub-title">
{t("tts.TtsModelListPage.form.categoryFiltersLabel")}
</label>
{categoryFieldGroups}
</label> */}
{/* {categoryFieldGroups} */}
{/* Model Dropdown */}
<label className="sub-title">
@@ -317,7 +319,9 @@ export function MultiDropdownSearch(props: Props) {
className={selectClasses}
name="tts-model-select"
onChange={handleChangeVoice}
onClick={() => { Analytics.ttsSelectVoiceFromCategory() }}
onClick={() => {
Analytics.ttsSelectVoiceFromCategory();
}}
disabled={isLoading}
>
{isLoading
@@ -38,7 +38,11 @@ import { TwitchTtsNotice } from "./notices/TwitchTtsNotice";
import { PleaseFollowNotice } from "./notices/PleaseFollowNotice";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faTrash,
faArrowRight,
faBarsStaggered,
faChevronRight,
faDeleteLeft,
faGlobe,
faVolumeHigh,
faVolumeUp,
} from "@fortawesome/free-solid-svg-icons";
@@ -253,7 +257,7 @@ function TtsModelListPage(props: Props) {
if (props.maybeSelectedTtsModel) {
let modelLink = `/tts/${props.maybeSelectedTtsModel.model_token}`;
let modelName = props.maybeSelectedTtsModel.title;
// let modelName = props.maybeSelectedTtsModel.title;
let userName = props.maybeSelectedTtsModel.creator_display_name;
directViewLink = (
<Link
@@ -261,18 +265,31 @@ function TtsModelListPage(props: Props) {
onClick={() => {
Analytics.ttsClickModelDetailsLink();
}}
className="py-2"
className="d-flex flex-column flex-lg-row gap-3 direct-view-link zi-2 align-items-lg-center mb-4"
>
<Trans i18nKey="tts.TtsModelListPage.form.modelSeeMoreLink">
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}
username={props.maybeSelectedTtsModel.creator_display_name}
email_hash={props.maybeSelectedTtsModel.creator_gravatar_hash}
/>
<div className="flex-grow-1">
<p>
Model by{" "}
<Link to="profile/Vegito1089" className="fw-semibold">
{userName}{" "}
<Gravatar
size={20}
username={props.maybeSelectedTtsModel.creator_display_name}
email_hash={props.maybeSelectedTtsModel.creator_gravatar_hash}
/>
</Link>{" "}
| <FontAwesomeIcon icon={faGlobe} className="me-2" />
Language: <span className="fw-semibold">English</span> | Use count:{" "}
<span className="fw-semibold">616400</span>
</p>
</div>
{/* <Trans i18nKey="tts.TtsModelListPage.form.modelSeeMoreLink">
See more details
</Trans> */}
<div className="fw-semibold">
<span>See more details</span>
<FontAwesomeIcon icon={faChevronRight} className="ms-2" />
</div>
</Link>
);
}
@@ -401,7 +418,7 @@ function TtsModelListPage(props: Props) {
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
/>
<AutocompleteSearch
{/* <AutocompleteSearch
allTtsCategories={props.allTtsCategories}
allTtsModels={props.ttsModels}
allTtsModelsByTokenMap={props.allTtsModelsByTokenMap}
@@ -411,41 +428,81 @@ function TtsModelListPage(props: Props) {
setSelectedCategories={props.setSelectedCategories}
maybeSelectedTtsModel={props.maybeSelectedTtsModel}
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
/>
/> */}
{directViewLink}
<div className="text-input">
<textarea
onClick={() => {
Analytics.ttsClickTextInputBox();
}}
onChange={handleChangeText}
className="form-control fs-5"
style={{ minHeight: "200px" }}
value={props.textBuffer}
placeholder={t("tts.TtsModelListPage.form.textInputHint")}
></textarea>
<div className="row gx-5 gy-5">
<div className="col-12 col-lg-6 d-flex flex-column gap-3">
<div className="d-flex flex-column gap-3 h-100">
<label className="sub-title pb-0">Your Text</label>
<textarea
onClick={() => {
Analytics.ttsClickTextInputBox();
}}
onChange={handleChangeText}
className="form-control text-message h-100"
value={props.textBuffer}
placeholder={t(
"tts.TtsModelListPage.form.textInputHint"
)}
></textarea>
<div className="d-flex gap-3">
<button
className="btn btn-primary w-100"
disabled={remainingCharactersButtonDisabled}
>
<FontAwesomeIcon
icon={faVolumeHigh}
className="me-2"
/>
{t("tts.TtsModelListPage.form.buttons.speak")}
</button>
<button
className="btn btn-destructive w-25"
onClick={handleClearClick}
>
<FontAwesomeIcon
icon={faDeleteLeft}
className="me-2"
/>
{t("tts.TtsModelListPage.form.buttons.clear")}
</button>
</div>
</div>
</div>
<div className="col-12 col-lg-6">
<div className="d-flex flex-column gap-3">
<h4 className="text-center text-lg-start">
<FontAwesomeIcon
icon={faBarsStaggered}
className="me-3"
/>
Session TTS Results
</h4>
<div className="d-flex flex-column gap-3 session-tts-section">
{/* <div className="panel panel-inner text-center p-5 rounded-5">
<div className="d-flex flex-column opacity-75 h-100 justify-content-center">
<FontAwesomeIcon
icon={faHeadphonesSimple}
className="fs-3 mb-3"
/>
<h5 className="fw-semibold">No results yet</h5>
<p>Generated audio will appear here.</p>
</div>
</div> */}
<SessionTtsInferenceResultListFc
ttsInferenceJobs={props.ttsInferenceJobs}
sessionSubscriptionsWrapper={
props.sessionSubscriptionsWrapper
}
/>
</div>
</div>
</div>
</div>
{maybeError}
<div className="d-flex flex-column flex-md-row w-100 gap-3 mt-3">
<button
className="btn btn-primary w-100"
disabled={remainingCharactersButtonDisabled}
>
<FontAwesomeIcon icon={faVolumeHigh} className="me-2" />
{t("tts.TtsModelListPage.form.buttons.speak")}
</button>
<button
className="btn btn-destructive w-100"
onClick={handleClearClick}
>
<FontAwesomeIcon icon={faTrash} className="me-2" />
{t("tts.TtsModelListPage.form.buttons.clear")}
</button>
</div>
</form>
</div>
</div>
@@ -456,11 +513,6 @@ function TtsModelListPage(props: Props) {
</div> */}
</motion.div>
<SessionTtsInferenceResultListFc
ttsInferenceJobs={props.ttsInferenceJobs}
sessionSubscriptionsWrapper={props.sessionSubscriptionsWrapper}
/>
<SessionW2lInferenceResultListFc
w2lInferenceJobs={props.w2lInferenceJobs}
/>
@@ -59,7 +59,7 @@ export function TtsPageHero(props: Props) {
);
viewPricingButton = (
<>
<Link
<Link
to="/pricing"
onClick={() => {
Analytics.ttsClickHeroViewPricing();
@@ -79,7 +79,7 @@ export function TtsPageHero(props: Props) {
let url = `/profile/${displayName}`;
myProfileButton = (
<>
<Link
<Link
to={url}
onClick={() => {
Analytics.ttsClickHeroViewProfile();
+706 -66
View File
File diff suppressed because it is too large. Load diff