tts main, explore modal

This commit is contained in:
BFlat authored and Brandon Thomas committed 2023-01-18 04:54:02 -05:00
1 parent 7663f00c84
commit c52ef38bed
8 files changed
+593 -208

No files matched your search

+1
View File
@@ -39,6 +39,7 @@
"react-reveal": "^1.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "5.0.0",
"react-select": "^5.7.0",
"react-share": "^4.4.1",
"sass": "^1.57.1",
"typescript": "^3.7.5",
@@ -1,21 +1,24 @@
import { COMMON_TRANSLATIONS, MergeDeepDictionary } from '@storyteller/components/src/_i18n/CommonTranslations';
import {
COMMON_TRANSLATIONS,
MergeDeepDictionary,
} from "@storyteller/components/src/_i18n/CommonTranslations";
// Use \u{00a0} =   character literal
// NB: This is the new translation system design. Multiple, per-page or per-module files are easier
// NB: This is the new translation system design. Multiple, per-page or per-module files are easier
// to navigate and maintain than singular monolithic files. We'll gradually phase out the old system.
import * as de from './locales/de';
import * as en from './locales/en';
import * as es from './locales/es';
import * as fr from './locales/fr';
import * as hi from './locales/hi';
import * as id from './locales/id';
import * as it from './locales/it';
import * as ja from './locales/ja';
import * as ko from './locales/ko';
import * as pt from './locales/pt';
import * as vi from './locales/vi';
import * as zh from './locales/zh';
import * as de from "./locales/de";
import * as en from "./locales/en";
import * as es from "./locales/es";
import * as fr from "./locales/fr";
import * as hi from "./locales/hi";
import * as id from "./locales/id";
import * as it from "./locales/it";
import * as ja from "./locales/ja";
import * as ko from "./locales/ko";
import * as pt from "./locales/pt";
import * as vi from "./locales/vi";
import * as zh from "./locales/zh";
const NEW_TRANSLATIONS: any = {
de: { translation: de },
@@ -30,7 +33,7 @@ const NEW_TRANSLATIONS: any = {
pt: { translation: pt },
vi: { translation: vi },
zh: { translation: zh },
}
};
// Make it easy to "see" new translations. Comment out when not developing.
// NEW_TRANSLATIONS = DebugPrefixLeaves(NEW_TRANSLATIONS, '\u{2705} ');
@@ -42,271 +45,283 @@ const FAKEYOU_TRANSLATIONS: any = {
translation: {
coreUi: {
footerNav: {
apiDocs: 'API Docs',
aboutUs: 'About Us',
builtBy: 'Built by <1>echelon</1> in Atlanta.',
feed: 'Feed',
leaderboard: 'Leaderboard',
patrons: 'Patrons',
termsOfUse: 'Terms of Use',
textToSpeech: 'Text to Speech',
upload: 'Upload',
video: 'Video',
pricing: 'Pricing'
apiDocs: "API Docs",
aboutUs: "About Us",
builtBy: "Built by <1>echelon</1> in Atlanta.",
feed: "Feed",
leaderboard: "Leaderboard",
patrons: "Patrons",
termsOfUse: "Terms of Use",
textToSpeech: "Text to Speech",
upload: "Upload",
video: "Video",
pricing: "Pricing",
},
topNav: {
aboutUs: 'About Us',
community: 'Community',
contributeUpload: 'Contribute / Upload',
create: 'Create',
developers: 'Developers',
feed: 'Feed',
leaderboard: 'Leaderboard',
logout: 'Logout',
myData: 'My Data',
patrons: 'Patrons',
signUpLogin: 'Sign up / Login',
terms: 'Terms of Use',
video: 'Video',
aboutUs: "About Us",
community: "Community",
contributeUpload: "Contribute / Upload",
create: "Create",
developers: "Developers",
feed: "Feed",
leaderboard: "Leaderboard",
logout: "Logout",
myData: "My Data",
patrons: "Patrons",
signUpLogin: "Sign up / Login",
terms: "Terms of Use",
video: "Video",
},
},
notices: {
pleaseFollow: {
title: 'Sorry our site is so slow!',
title: "Sorry our site is so slow!",
body: "I am so sorry the website is slow. We're getting millions of requests. <1>Please follow us on Twitter</1> and also <3>join our Discord</3>. 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.",
}
},
},
pages: {
// Index page
ttsList: {
buttonClear: 'Clear',
buttonSpeak: 'Speak',
errorTooManyRequests: "<strong>You're sending too many requests!</strong> Slow down a little. We have to slow things down a little when the server gets busy.",
heroSubtitle: 'Use <strong>FakeYou</strong> deep fake tech to say stuff with your favorite characters',
heroTitle: 'Text to Speech',
placeholderTextGoesHere: 'Textual shenanigans go here...',
buttonClear: "Clear",
buttonSpeak: "Speak",
errorTooManyRequests:
"<strong>You're sending too many requests!</strong> Slow down a little. We have to slow things down a little when the server gets busy.",
heroSubtitle:
"Use <strong>FakeYou</strong> deep fake tech to say stuff with your favorite characters",
heroTitle: "Text to Speech",
placeholderTextGoesHere: "Textual shenanigans go here...",
},
// Other pages
contributeIndex: {
buttonCreateCategory: 'Create category',
buttonSuggestCategory: 'Suggest category',
buttonUploadVoice: 'Upload voice (TTS model)',
buttonUploadW2lPhoto: 'Upload lipsync photo (w2l)',
buttonUploadW2lVideo: 'Upload lipsync video (w2l)',
describeMore: 'Want to contribute code, design, or data science? <1 />',
describeSuggest: 'Help us organize the models!',
describeUploadModels: 'Create new voices and video templates for FakeYou. <1 /> to learn how.',
discordLink1: 'Join our Discord',
discordLink2: 'Say hi in Discord',
headingCreateCategory: 'Create categories',
headingMore: 'More Ways to Contribute',
headingSuggestCategory: 'Suggest categories',
headingUploadModels: 'Upload Models',
heroSubtitle: 'You make FakeYou <strong>better</strong> by contributing',
heroTitle: 'Contribute to FakeYou!',
introText: "You'll get credited for everything you contribute. You'll also get queue priority, be eligible to win prizes, and help us become a Hollywood-killing deepfake tooling, streaming, and filmmaking powerhouse.",
buttonCreateCategory: "Create category",
buttonSuggestCategory: "Suggest category",
buttonUploadVoice: "Upload voice (TTS model)",
buttonUploadW2lPhoto: "Upload lipsync photo (w2l)",
buttonUploadW2lVideo: "Upload lipsync video (w2l)",
describeMore:
"Want to contribute code, design, or data science? <1 />",
describeSuggest: "Help us organize the models!",
describeUploadModels:
"Create new voices and video templates for FakeYou. <1 /> to learn how.",
discordLink1: "Join our Discord",
discordLink2: "Say hi in Discord",
headingCreateCategory: "Create categories",
headingMore: "More Ways to Contribute",
headingSuggestCategory: "Suggest categories",
headingUploadModels: "Upload Models",
heroSubtitle:
"You make FakeYou <strong>better</strong> by contributing",
heroTitle: "Contribute to FakeYou!",
introText:
"You'll get credited for everything you contribute. You'll also get queue priority, be eligible to win prizes, and help us become a Hollywood-killing deepfake tooling, streaming, and filmmaking powerhouse.",
},
},
ttsListPage: {
by: 'by',
categoryFilters: 'Category Filters', // "Category / Language" in other locales
loading: 'Loading...',
search: 'Search',
searchTerm: 'Search Term',
seeModelDetails: 'See more details about the "<1>{{modelName}}</1>" model by <3>{{userName}}</3>\u{00a0}',
voiceCount: 'Voice ({{count}} to choose from)',
}
}
by: "by",
categoryFilters: "Category Filters", // "Category / Language" in other locales
loading: "Loading...",
search: "Search",
searchTerm: "Search Term",
seeModelDetails:
'See more details about the "<1>{{modelName}}</1>" model by <3>{{userName}}</3>\u{00a0}',
voiceCount: "Voice ({{count}} to choose from)",
},
},
},
// Spanish: 10.5% Twitch (#2), 20+% FakeYou (#2)
es: {
translation: {
coreUi: {
footerNav: {
apiDocs: 'Documentos de la API',
aboutUs: 'Sobre Nosotros',
builtBy: 'Construido por <1>echelon</1> en Atlanta.',
feed: 'Transmisión en Vivo',
leaderboard: 'Tabla\u{00a0}de\u{00a0}Clasificación',
patrons: 'Mecenas',
termsOfUse: 'Términos\u{00a0}de\u{00a0}Uso',
textToSpeech: 'Texto a Voz',
upload: 'Subir',
video: 'Video', // NB: This *is* translated
apiDocs: "Documentos de la API",
aboutUs: "Sobre Nosotros",
builtBy: "Construido por <1>echelon</1> en Atlanta.",
feed: "Transmisión en Vivo",
leaderboard: "Tabla\u{00a0}de\u{00a0}Clasificación",
patrons: "Mecenas",
termsOfUse: "Términos\u{00a0}de\u{00a0}Uso",
textToSpeech: "Texto a Voz",
upload: "Subir",
video: "Video", // NB: This *is* translated
},
topNav: {
aboutUs: 'Sobre Nosotros',
community: 'Comunidad',
contributeUpload: 'Contribuir / Subir',
developers: 'Desarrollador',
feed: 'Transmisión en Vivo',
leaderboard: 'Tabla de Clasificación',
logout: 'Cerrar sesión',
myData: 'Mis datos',
patrons: 'Mecenas',
signUpLogin: 'Registrate e inicia secion',
terms: 'Términos de Uso',
video: 'Video', // NB: This *is* translated
aboutUs: "Sobre Nosotros",
community: "Comunidad",
contributeUpload: "Contribuir / Subir",
developers: "Desarrollador",
feed: "Transmisión en Vivo",
leaderboard: "Tabla de Clasificación",
logout: "Cerrar sesión",
myData: "Mis datos",
patrons: "Mecenas",
signUpLogin: "Registrate e inicia secion",
terms: "Términos de Uso",
video: "Video", // NB: This *is* translated
},
},
notices: {
pleaseFollow: {
title: '¡Lo sentimos, nuestro sitio es tan lento!',
title: "¡Lo sentimos, nuestro sitio es tan lento!",
body: "Lamento mucho que el sitio web sea lento. Estamos recibiendo millones de solicitudes. <1>Síganos en Twitter</1> y también únase a nuestro <3>Discord</3>. Voy a presentar un procesamiento más rápido (menos de un minuto) para aquellos que nos siguen y ayudan a respaldar nuestro trabajo. Así que sigue nuestro Twitter y únete a nuestro Discord. <5>Nuestra nueva tecnología de videos falsos profundos debutará en Twitch</5>, así que síganos allí también.",
}
},
},
pages: {
// Index page
ttsList: {
buttonClear: 'Claro',
buttonSpeak: 'Hablar',
errorTooManyRequests: "<strong>¡Estás enviando demasiadas solicitudes!</strong> Reduzca la velocidad un poco. Tenemos que ralentizar un poco las cosas cuando el servidor está ocupado. ",
heroSubtitle: 'Usa <strong>FakeYou</strong> tecnología falsa profunda para decir cosas con tus personajes favoritos',
heroTitle: 'Texto a Voz',
placeholderTextGoesHere: 'Las travesuras textuales van aquí...',
buttonClear: "Claro",
buttonSpeak: "Hablar",
errorTooManyRequests:
"<strong>¡Estás enviando demasiadas solicitudes!</strong> Reduzca la velocidad un poco. Tenemos que ralentizar un poco las cosas cuando el servidor está ocupado. ",
heroSubtitle:
"Usa <strong>FakeYou</strong> tecnología falsa profunda para decir cosas con tus personajes favoritos",
heroTitle: "Texto a Voz",
placeholderTextGoesHere: "Las travesuras textuales van aquí...",
},
// Other pages
contributeIndex: {
buttonCreateCategory: 'Crear categoría',
buttonSuggestCategory: 'Sugerir categoría',
buttonUploadVoice: 'Subir voz (modelo TTS)',
buttonUploadW2lPhoto: 'Foto de sincronización de labios (w2l)', // NB: Remove 'Subdir' ~= upload
buttonUploadW2lVideo: 'Video de sincronización de labios (w2l)', // NB: Remove 'Subdir' ~= upload
describeMore: '¿Quiere contribuir con código, diseño o ciencia de datos? <1 />',
describeSuggest: '¡Ayúdanos a organizar los modelos!',
describeUploadModels: 'Crea nuevas voces y plantillas de video para FakeYou. <1 /> para aprender cómo.',
discordLink1: 'Únase a nuestro Discord',
discordLink2: '¡Saluda en Discord!',
headingCreateCategory: 'Crear categorías',
headingMore: 'Más Formas de Contribuir',
headingSuggestCategory: 'Sugerir categorías',
headingUploadModels: 'Subir Modelos',
heroSubtitle: 'Haces FakeYou <strong>mejor</strong> contribuyendo',
heroTitle: 'Contribuir a FakeYou',
introText: "Recibirás crédito por todo lo que contribuyas. También obtendrá prioridad en la cola, será elegible para ganar premios y nos ayudará a convertirnos en una potencia de herramientas, transmisión y cine de deepfake que acaba con Hollywood.",
buttonCreateCategory: "Crear categoría",
buttonSuggestCategory: "Sugerir categoría",
buttonUploadVoice: "Subir voz (modelo TTS)",
buttonUploadW2lPhoto: "Foto de sincronización de labios (w2l)", // NB: Remove 'Subdir' ~= upload
buttonUploadW2lVideo: "Video de sincronización de labios (w2l)", // NB: Remove 'Subdir' ~= upload
describeMore:
"¿Quiere contribuir con código, diseño o ciencia de datos? <1 />",
describeSuggest: "¡Ayúdanos a organizar los modelos!",
describeUploadModels:
"Crea nuevas voces y plantillas de video para FakeYou. <1 /> para aprender cómo.",
discordLink1: "Únase a nuestro Discord",
discordLink2: "¡Saluda en Discord!",
headingCreateCategory: "Crear categorías",
headingMore: "Más Formas de Contribuir",
headingSuggestCategory: "Sugerir categorías",
headingUploadModels: "Subir Modelos",
heroSubtitle: "Haces FakeYou <strong>mejor</strong> contribuyendo",
heroTitle: "Contribuir a FakeYou",
introText:
"Recibirás crédito por todo lo que contribuyas. También obtendrá prioridad en la cola, será elegible para ganar premios y nos ayudará a convertirnos en una potencia de herramientas, transmisión y cine de deepfake que acaba con Hollywood.",
},
},
ttsListPage: {
by: 'de',
categoryFilters: 'Categoría / Idioma',
loading: 'Cargando...',
search: 'Búsqueda',
searchTerm: 'Término de búsqueda',
seeModelDetails: 'Ver más detalles sobre el modelo "<1>{{modelName}}</1>" de <3>{{userName}}</3>\u{00a0}',
voiceCount: 'Voz ({{count}} para elegir)',
}
}
by: "de",
categoryFilters: "Categoría / Idioma",
loading: "Cargando...",
search: "Búsqueda",
searchTerm: "Término de búsqueda",
seeModelDetails:
'Ver más detalles sobre el modelo "<1>{{modelName}}</1>" de <3>{{userName}}</3>\u{00a0}',
voiceCount: "Voz ({{count}} para elegir)",
},
},
},
// ---------- OTHER LANGUAGES ----------
// German: 6.5% Twitch (#4)
de: {
translation: {
}
translation: {},
},
// French: 5.6% Twitch (#6)
fr: {
translation: {
}
translation: {},
},
// Indonesian 2% FakeYou
id: {
translation: {
}
translation: {},
},
// Japanese: 2.5% Twitch (#8)
ja: {
translation: {
coreUi: {
topNav: {
community: 'コミュニティ',
contributeUpload: '投稿 / アップロード',
logout: 'ログアウト',
myData: '私のデータ',
signUpLogin: 'サインアップ / ログイン',
video: 'Video', // NB: Katakana here gets forced horizontal for some reason
community: "コミュニティ",
contributeUpload: "投稿 / アップロード",
logout: "ログアウト",
myData: "私のデータ",
signUpLogin: "サインアップ / ログイン",
video: "Video", // NB: Katakana here gets forced horizontal for some reason
},
},
pages: {
ttsList: {
heroTitle: 'テキスト読み上げ',
heroSubtitle: '<strong>FakeYou</strong>ディープフェイクテックを使用して、お気に入りのキャラクターと何かを言いましょう。',
heroTitle: "テキスト読み上げ",
heroSubtitle:
"<strong>FakeYou</strong>ディープフェイクテックを使用して、お気に入りのキャラクターと何かを言いましょう。",
},
},
ttsListPage: {
categoryFilters: 'カテゴリ / 言語',
loading: '読み込んでいます...',
search: '検索',
searchTerm: '検索語',
speakButton: '話す',
clearButton: 'クリア',
}
}
categoryFilters: "カテゴリ / 言語",
loading: "読み込んでいます...",
search: "検索",
searchTerm: "検索語",
speakButton: "話す",
clearButton: "クリア",
},
},
},
// Korean: 5.4% Twitch (#7)
ko: {
translation: {
}
translation: {},
},
// Portuguese: 6.2% Twitch (#5)
pt: {
translation: {
coreUi: {
topNav: {
community: 'Comunidade',
contributeUpload: 'Contribuir / Carregar',
logout: 'Sair',
myData: 'Meus dados',
signUpLogin: 'Inscreva-se / Faça login',
video: 'Vídeo',
community: "Comunidade",
contributeUpload: "Contribuir / Carregar",
logout: "Sair",
myData: "Meus dados",
signUpLogin: "Inscreva-se / Faça login",
video: "Vídeo",
},
},
notices: {
pleaseFollow: {
title: 'Desculpe, nosso site é tão lento!',
title: "Desculpe, nosso site é tão lento!",
body: "Sinto muito que o site esteja lento. Estamos recebendo milhões de solicitações. <1>Por favor, siga-nos no Twitter</1> e também <3>entre no nosso Discord</3>. Vou apresentar um processamento mais rápido (menos de um minuto) para aqueles que nos seguem e ajudam a apoiar nosso trabalho. Então, por favor, siga nosso Twitter e participe do nosso Discord. <5>Nossa nova tecnologia de deepfake de vídeo será lançada no Twitch</5>, então siga-nos lá também.",
}
},
},
pages: {
ttsList: {
heroTitle: 'Texto para Fala',
heroSubtitle: 'Use a tecnologia deepfake do <strong>FakeYou</strong> para dizer coisas com seus personagens favoritos.',
errorTooManyRequests: "<strong>Você está enviando muitos pedidos!</strong> Desacelere um pouco. Temos que desacelerar um pouco as coisas quando o servidor fica ocupado.",
heroTitle: "Texto para Fala",
heroSubtitle:
"Use a tecnologia deepfake do <strong>FakeYou</strong> para dizer coisas com seus personagens favoritos.",
errorTooManyRequests:
"<strong>Você está enviando muitos pedidos!</strong> Desacelere um pouco. Temos que desacelerar um pouco as coisas quando o servidor fica ocupado.",
},
},
ttsListPage: {
categoryFilters: 'Categoria / Idioma',
loading: 'Carregando...',
search: 'Procurar',
searchTerm: 'Termo de pesquisa',
speakButton: 'Falar',
clearButton: 'Claro',
}
}
categoryFilters: "Categoria / Idioma",
loading: "Carregando...",
search: "Procurar",
searchTerm: "Termo de pesquisa",
speakButton: "Falar",
clearButton: "Claro",
},
},
},
// 6.5% Twitch (#3)
ru: {
translation: {
}
translation: {},
},
// Turkish: 4% FakeYou (#3)
tr: {
translation: {
pages: {
ttsList: {
heroTitle: 'Konuşma Metni',
heroSubtitle: 'En sevdiğiniz karakterlerle bir şeyler söylemek için <strong>FakeYou</strong> derin sahte teknolojisini kullanın.',
heroTitle: "Konuşma Metni",
heroSubtitle:
"En sevdiğiniz karakterlerle bir şeyler söylemek için <strong>FakeYou</strong> derin sahte teknolojisini kullanın.",
},
},
}
},
},
}
};
// TODO: Type these as i18next dictionaries
const FAKEYOU_MERGED_TRANSLATIONS: any = MergeDeepDictionary(
NEW_TRANSLATIONS,
NEW_TRANSLATIONS,
MergeDeepDictionary(FAKEYOU_TRANSLATIONS, COMMON_TRANSLATIONS)
);
export { FAKEYOU_MERGED_TRANSLATIONS }
export { FAKEYOU_MERGED_TRANSLATIONS };
+121 -8
View File
@@ -103,6 +103,10 @@ styles with important tags:
font-weight: 600;
}
.fw-medium {
font-weight: 500;
}
.container {
max-width: 1080px !important;
}
@@ -237,7 +241,12 @@ styles with important tags:
border-radius: 0px;
.panel-inner {
background-color: lighten($panel, 2%);
background-color: lighten($panel, 4%);
}
.panel-tts-results {
border-radius: 5px;
background-color: lighten($panel, 4%);
}
.panel-title {
@@ -315,6 +324,9 @@ styles with important tags:
.form-control {
border-radius: 5px;
background-color: $input-dark !important;
border-color: $input-dark !important;
color: $white !important;
}
.form-control,
@@ -623,10 +635,11 @@ styles with important tags:
height: 450px;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
}
.direct-view-link {
background-color: lighten($panel, 2%);
background-color: lighten($panel, 4%);
border: 1px solid #39394c;
border-radius: 5px;
padding: 11px 16px;
@@ -635,6 +648,100 @@ styles with important tags:
border-color: lighten(#39394c, 10%);
}
}
.input-icon-search {
.form-control-feedback {
padding: 12px 18px;
position: absolute;
z-index: 2;
width: 2.375rem;
// height: 2.375rem;
// line-height: 2.69rem;
text-align: center;
pointer-events: none;
color: $white;
opacity: 0.9;
}
}
.select-search {
height: 48px;
border-width: 2px;
padding-left: 2.25rem;
padding-right: 0.5rem;
background-color: $input-dark;
border-radius: 50px;
border-color: $input-dark !important;
box-shadow: none;
cursor: pointer;
&:hover {
background-color: lighten($input-dark, 5%);
border-color: lighten($input-dark, 5%) !important;
}
&.focused {
border-color: $primary !important;
}
}
.select-option {
background-color: $input-dark;
cursor: pointer;
padding: 0.5rem 1rem;
&:hover {
background-color: lighten($input-dark, 8%);
}
}
.select-input,
.select-value {
color: $white;
}
.select-placeholder {
color: $white !important;
}
.select-container {
background: $input-dark;
margin-top: 6px;
padding: 0;
border-radius: 5px;
z-index: 3;
}
.select-separator {
display: none;
}
.rounded-50 {
border-radius: 50px;
}
.modal-content {
background-color: $panel;
border-color: lighten($panel, 8%) !important;
border: 1px solid;
border-radius: 8px;
box-shadow: 0px 9px 33px 1px rgba(19, 19, 27, 0.8);
-webkit-box-shadow: 0px 9px 33px 1px rgba(19, 19, 27, 0.8);
-moz-box-shadow: 0px 9px 33px 1px rgba(19, 19, 27, 0.8);
min-height: 600px;
}
.modal-header {
border-bottom: 1px solid lighten($panel, 8%);
}
.modal-backdrop {
background-color: #0d0d14;
}
.modal-header .btn-close {
filter: brightness(0) invert(1);
}
}
select {
@@ -668,6 +775,7 @@ textarea {
&.text-message {
font-size: 18px;
font-weight: 300;
min-height: 200px !important;
}
}
@@ -697,11 +805,11 @@ textarea {
color: $white !important;
}
input {
background-color: $input !important;
border-color: $input !important;
color: $white !important;
}
// input {
// background-color: $input !important;
// border-color: $input !important;
// color: $white !important;
// }
.img-product {
&.img-tts {
@@ -737,7 +845,12 @@ input {
.zi-2 {
position: relative;
z-index: 2;
z-index: 2 !important;
}
.zi-3 {
position: relative;
z-index: 3 !important;
}
@media (min-width: 992px) {
@@ -8,10 +8,9 @@ import {
faClock,
faLink,
faHeadphonesSimple,
faMicrophone,
} from "@fortawesome/free-solid-svg-icons";
import { motion } from "framer-motion";
import { container, item, sessionItem } from "../../../data/animation";
import { container, sessionItem } from "../../../data/animation";
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
import { Analytics } from "../../../common/Analytics";
@@ -25,7 +24,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
props.ttsInferenceJobs.forEach((job) => {
if (!job.maybeResultToken) {
let cssStyle = "alert alert-secondary mx-3 mx-md-0 mb-0";
let cssStyle = "alert alert-secondary mb-0";
let stateDescription = "Pending...";
switch (job.jobState) {
@@ -37,24 +36,24 @@ function SessionTtsInferenceResultListFc(props: Props) {
: job.maybeExtraStatusDescription;
break;
case JobState.STARTED:
cssStyle = "alert alert-success mx-3 mx-md-0 mb-0";
cssStyle = "alert alert-success mb-0";
stateDescription =
job.maybeExtraStatusDescription == null
? "Started..."
: job.maybeExtraStatusDescription;
break;
case JobState.ATTEMPT_FAILED:
cssStyle = "alert alert-danger mx-3 mx-md-0 mb-0";
cssStyle = "alert alert-danger 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 mb-0";
cssStyle = "alert alert-danger 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 mb-0";
cssStyle = "message is-success mb-0";
stateDescription = "Success!"; // Not sure why we're here instead of other branch!
break;
}
@@ -83,7 +82,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
</div>*/}
<div>
<motion.div
className="panel panel-inner p-4 gap-3 d-flex flex-column"
className="panel panel-tts-results p-4 gap-3 d-flex flex-column"
variants={sessionItem}
>
<div>
@@ -144,7 +143,7 @@ function SessionTtsInferenceResultListFc(props: Props) {
!props.sessionSubscriptionsWrapper.hasPaidFeatures()
) {
upgradeNotice = (
<div className="d-flex flex-column gap-3 mx-3 mx-md-0 sticky-top">
<div className="d-flex flex-column gap-3 sticky-top zi-2">
<motion.div
className="alert alert-warning alert-cta mb-0"
variants={sessionItem}
@@ -297,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">
@@ -0,0 +1,14 @@
export const SearchFieldClass = {
control: (state: any) =>
state.isFocused ? "select-search focused" : "select-search",
option: (state: any) => (state.isFocused ? "select-option" : "select-option"),
input: (state: any) => (state.isFocused ? "select-input" : "select-input"),
placeholder: (state: any) =>
state.isFocused ? "select-placeholder" : "select-placeholder",
singleValue: (state: any) =>
state.isFocused ? "select-value" : "select-value",
menu: (state: any) =>
state.isFocused ? "select-container" : "select-container",
indicatorSeparator: (state: any) =>
state.isFocused ? "select-separator" : "select-separator",
};
@@ -0,0 +1,59 @@
import React, { useState } from "react";
import { TtsModelListItem } from "@storyteller/components/src/api/tts/ListTtsModels";
import { TtsCategoryType } from "../../../../AppWrapper";
import Autocomplete from "react-autocomplete";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMicrophone, faSearch } from "@fortawesome/free-solid-svg-icons";
import { t } from "i18next";
import { Analytics } from "../../../../common/Analytics";
import Select from "react-select";
import AsyncSelect from "react-select/async";
import { SearchFieldClass } from "./SearchFieldClass";
// NB: This probably is not the best autocomplete library in the world
// A lot of the libraries are really old and depend on jQuery (gross).
// This one seemed to be simple and minimal, but unfortunately it doesn't
// use any sort of Trie or caching, and it's almost too minimal.
interface Props {
allTtsCategories: TtsCategoryType[];
allTtsModels: TtsModelListItem[];
allTtsModelsByTokenMap: Map<string, TtsModelListItem>;
dropdownCategories: TtsCategoryType[][];
setDropdownCategories: (dropdownCategories: TtsCategoryType[][]) => void;
selectedCategories: TtsCategoryType[];
setSelectedCategories: (selectedCategories: TtsCategoryType[]) => void;
maybeSelectedTtsModel?: TtsModelListItem;
setMaybeSelectedTtsModel: (maybeSelectedTtsModel: TtsModelListItem) => void;
}
export function SelectSearch(props: Props) {
// const [searchValue, setSearchValue] = useState<string>("");
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
];
return (
<>
<div className="zi-3 input-icon-search">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faMicrophone} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
/>
</div>
</>
);
}
@@ -29,7 +29,7 @@ import {
} from "../../../api/category/ListTtsCategories";
import { MultiDropdownSearch } from "./MultiDropdownSearch";
import { TtsCategoryType } from "../../../../AppWrapper";
import { AutocompleteSearch } from "./AutocompleteSearch";
import { SelectSearch } from "./SelectSearch";
import { LanguageNotice } from "./notices/LanguageNotice";
import { Language } from "@storyteller/components/src/i18n/Language";
import { t } from "i18next";
@@ -39,10 +39,17 @@ import { PleaseFollowNotice } from "./notices/PleaseFollowNotice";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faArrowRight,
faArrowRightLong,
faBarsStaggered,
faCaretRight,
faChevronRight,
faCompass,
faDeleteLeft,
faGlobe,
faMicrophone,
faShuffle,
faTag,
faTags,
faVolumeHigh,
faVolumeUp,
} from "@fortawesome/free-solid-svg-icons";
@@ -62,6 +69,9 @@ import {
import {
DynamicallyCategorizeModels,
} from "../../../../model/categories/SyntheticCategory";
import Select from "react-select";
import AsyncSelect from "react-select/async";
import { SearchFieldClass } from "./SearchFieldClass";
export interface EnqueueJobResponsePayload {
success: boolean;
@@ -270,7 +280,7 @@ function TtsModelListPage(props: Props) {
<div className="flex-grow-1">
<p>
Model by{" "}
<Link to="profile/Vegito1089" className="fw-semibold">
<Link to="profile/Vegito1089" className="fw-medium">
{userName}{" "}
<Gravatar
size={20}
@@ -286,7 +296,7 @@ function TtsModelListPage(props: Props) {
{/* <Trans i18nKey="tts.TtsModelListPage.form.modelSeeMoreLink">
See more details
</Trans> */}
<div className="fw-semibold">
<div className="fw-medium">
<span>See more details</span>
<FontAwesomeIcon icon={faChevronRight} className="ms-2" />
</div>
@@ -371,6 +381,15 @@ function TtsModelListPage(props: Props) {
}
}
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
];
// NB: If the text is too long, don't allow submission
let remainingCharactersButtonDisabled = props.textBuffer.trim().length > 1024;
@@ -404,7 +423,7 @@ function TtsModelListPage(props: Props) {
className="w-100 d-flex flex-column gap-4"
onSubmit={handleFormSubmit}
>
<MultiDropdownSearch
{/* <MultiDropdownSearch
allTtsCategories={props.allTtsCategories}
allTtsModels={props.ttsModels}
allTtsCategoriesByTokenMap={props.allTtsCategoriesByTokenMap}
@@ -416,8 +435,7 @@ function TtsModelListPage(props: Props) {
setSelectedCategories={props.setSelectedCategories}
maybeSelectedTtsModel={props.maybeSelectedTtsModel}
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
/>
/> */}
{/* <AutocompleteSearch
allTtsCategories={props.allTtsCategories}
allTtsModels={props.ttsModels}
@@ -429,13 +447,180 @@ function TtsModelListPage(props: Props) {
maybeSelectedTtsModel={props.maybeSelectedTtsModel}
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
/> */}
<div>
<div className="d-flex gap-2">
<label className="sub-title">Select Voice</label>
<a href="/" className="ms-1">
<FontAwesomeIcon icon={faShuffle} />
</a>
</div>
<div className="d-flex flex-column flex-lg-row gap-3 ">
<div className="flex-grow-1">
<SelectSearch
allTtsCategories={props.allTtsCategories}
allTtsModels={props.ttsModels}
allTtsModelsByTokenMap={props.allTtsModelsByTokenMap}
dropdownCategories={props.dropdownCategories}
setDropdownCategories={props.setDropdownCategories}
selectedCategories={props.selectedCategories}
setSelectedCategories={props.setSelectedCategories}
maybeSelectedTtsModel={props.maybeSelectedTtsModel}
setMaybeSelectedTtsModel={
props.setMaybeSelectedTtsModel
}
/>
</div>
<button
onClick={handleClearClick}
className="btn btn-primary rounded-50"
data-bs-toggle="modal"
data-bs-target="#exploreModal"
>
<FontAwesomeIcon icon={faCompass} className="me-2" />
Explore Voices
</button>
</div>
</div>
{/* Explore Modal */}
<div
className="modal fade"
id="exploreModal"
aria-labelledby="ModalLabel"
aria-hidden="true"
>
<div className="modal-dialog modal-xl modal-fullscreen-lg-down modal-dialog-centered modal-dialog-scrollable">
<div className="modal-content">
<div className="modal-header p-3">
<h5 className="modal-title fw-semibold" id="ModalLabel">
<FontAwesomeIcon icon={faCompass} className="me-3" />
Explore Voices
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body p-3 p-lg-4">
<div className="row gx-3 gy-3">
<div className="col-12 col-lg-3 input-icon-search">
<label className="sub-title">Language</label>
<div>
<span className="form-control-feedback">
<FontAwesomeIcon icon={faGlobe} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
/>
</div>
</div>
<div className="col-12 col-md-12 col-lg-9 input-icon-search">
<div className="d-flex">
<label className="sub-title flex-grow-1">
Category
</label>
<a href="/" className="ms-3 fw-medium">
Clear category filters
</a>
</div>
<div className="d-flex flex-column flex-md-row gap-2">
<div className="w-100">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
className="w-100"
/>
</div>
<div className="d-none d-md-flex align-items-center">
<FontAwesomeIcon
icon={faArrowRightLong}
className="fs-6 opacity-75"
/>
</div>
<div className="w-100">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
className="w-100"
/>
</div>
<div className="d-none d-md-flex align-items-center">
<FontAwesomeIcon
icon={faArrowRightLong}
className="fs-6 opacity-75"
/>
</div>
<div className="w-100">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
className="w-100"
/>
</div>
</div>
</div>
{/* <div className="col-12 col-lg-3 input-icon-search">
<label className="sub-title">Sub-category 1</label>
<div>
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
/>
</div>
</div>
<div className="col-12 col-lg-3 input-icon-search">
<label className="sub-title">Sub-category 2</label>
<div>
<span className="form-control-feedback">
<FontAwesomeIcon icon={faTags} />
</span>
<Select
defaultValue={options[2]}
options={options}
classNames={SearchFieldClass}
/>
</div>
</div> */}
</div>
</div>
</div>
</div>
</div>
{directViewLink}
<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>
<div className="d-flex gap-2">
<label className="sub-title pb-0">Your Text</label>
<a href="/" className="ms-1">
<FontAwesomeIcon icon={faShuffle} />
</a>
</div>
<textarea
onClick={() => {
Analytics.ttsClickTextInputBox();
@@ -501,7 +686,6 @@ function TtsModelListPage(props: Props) {
</div>
</div>
</div>
{maybeError}
</form>
</div>