explore slide from top

This commit is contained in:
BFlat committed 2023-01-27 15:06:57 +07:00
1 parent b3e9e4aceb
commit ec4e5f77ca
4 files changed
+97 -89

No files matched your search

@@ -834,7 +834,7 @@ styles with important tags:
opacity: 0;
height: 0;
transition-property: none !important;
transition: all 0.05s !important;
transition: all 0.1s !important;
transition-timing-function: ease !important;
}
.sliding-content.open {
@@ -842,7 +842,7 @@ styles with important tags:
opacity: 1;
height: 100%;
transition-property: none !important;
transition: all 0.2s !important;
transition: all 0.4s !important;
transition-timing-function: ease !important;
}
}
@@ -150,11 +150,9 @@ function TtsModelListPage(props: Props) {
return () => clearTimeout(timeout);
}, []);
const [isSliding, setIsSliding] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const handleClick = () => {
setIsSliding(!isSliding);
const handleClickExplore = () => {
setIsOpen(!isOpen);
};
@@ -523,60 +521,10 @@ function TtsModelListPage(props: Props) {
className="w-100 d-flex flex-column"
onSubmit={handleFormSubmit}
>
<div className="pb-4">
<div className="d-flex gap-2">
<label className="sub-title">
{t("tts.TtsModelListPage.form.searchBarLabel")}
</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
}
selectedTtsLanguageScope={
props.selectedTtsLanguageScope
}
/>
</div>
<button
onClick={handleClick}
// onClick={() => {
// Analytics.ttsOpenExploreVoicesModal();
// }}
className="btn btn-primary rounded-50"
type="button"
>
<FontAwesomeIcon
icon={isOpen ? faChevronUp : faChevronDown}
className="me-2"
/>
{t(
"tts.TtsModelListPage.exploreModal.exploreModalOpenButton"
)}
</button>
</div>
</div>
{/* Explore Modal */}
{/* Explore Rollout */}
<div
className={`sliding-content ${
isSliding ? "open pb-4 mt-2 mb-3" : "closed"
isOpen ? "open pb-4" : "closed"
}`}
>
<ExploreVoicesModal
@@ -600,6 +548,57 @@ function TtsModelListPage(props: Props) {
/>
</div>
<div className="pb-4">
<div className="d-flex gap-2">
<label className="sub-title">
{t("tts.TtsModelListPage.form.searchBarLabel")}
</label>
{/*<a href="/" className="ms-1">
<FontAwesomeIcon icon={faShuffle} />
</a>*/}
</div>
<div className="d-flex flex-column flex-lg-row gap-3 zi-2">
<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
}
selectedTtsLanguageScope={
props.selectedTtsLanguageScope
}
/>
</div>
{}
<button
onClick={handleClickExplore}
// onClick={() => {
// Analytics.ttsOpenExploreVoicesModal();
// }}
className="btn btn-primary rounded-50"
type="button"
>
<FontAwesomeIcon
icon={isOpen ? faChevronUp : faChevronDown}
className="me-2"
/>
{t(
"tts.TtsModelListPage.exploreModal.exploreModalOpenButton"
)}
</button>
</div>
</div>
{directViewLink}
<div className="row gx-5 gy-5">
@@ -5,7 +5,7 @@ import { LanguageOptions } from "./LanguageOptions";
import { TtsCategoryType } from "../../../../../../AppWrapper";
import { TtsModelListItem } from "@storyteller/components/src/api/tts/ListTtsModels";
import { CategoryOptions } from "./CategoryOptions";
// import { ScopedVoiceModelOptions } from "./ScopedVoiceModelOptions";
import { ScopedVoiceModelOptions } from "./ScopedVoiceModelOptions";
import { t } from "i18next";
interface Props {
@@ -108,6 +108,7 @@ export function ExploreVoicesModal(props: Props) {
onClick={() => {
handleChangeCategory(0, "*");
}}
type="button"
>
<FontAwesomeIcon icon={faEraser} className="me-2" />
{t("tts.TtsModelListPage.exploreModal.clearCategoryFilterButton")}
@@ -131,6 +132,20 @@ export function ExploreVoicesModal(props: Props) {
/>
</div>
</div>
<div className="mt-4">
<ScopedVoiceModelOptions
allTtsCategories={props.allTtsCategories}
allTtsModels={props.allTtsModels}
allTtsCategoriesByTokenMap={props.allTtsCategoriesByTokenMap}
allTtsModelsByTokenMap={props.allTtsModelsByTokenMap}
ttsModelsByCategoryToken={props.ttsModelsByCategoryToken}
dropdownCategories={props.dropdownCategories}
selectedCategories={props.selectedCategories}
maybeSelectedTtsModel={props.maybeSelectedTtsModel}
setMaybeSelectedTtsModel={props.setMaybeSelectedTtsModel}
selectedTtsLanguageScope={props.selectedTtsLanguageScope}
/>
</div>
</div>
);
}
@@ -1,8 +1,6 @@
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faMicrophone,
} from "@fortawesome/free-solid-svg-icons";
import { faMicrophone } from "@fortawesome/free-solid-svg-icons";
import { TtsModelListItem } from "@storyteller/components/src/api/tts/ListTtsModels";
import { TtsCategoryType } from "../../../../../../AppWrapper";
import { Trans } from "react-i18next";
@@ -25,7 +23,7 @@ interface Props {
maybeSelectedTtsModel?: TtsModelListItem;
setMaybeSelectedTtsModel: (maybeSelectedTtsModel: TtsModelListItem) => void;
selectedTtsLanguageScope: string,
selectedTtsLanguageScope: string;
}
export function ScopedVoiceModelOptions(props: Props) {
@@ -44,17 +42,16 @@ export function ScopedVoiceModelOptions(props: Props) {
if (maybeNewTtsModel !== undefined) {
props.setMaybeSelectedTtsModel(maybeNewTtsModel);
}
}
};
const leafiestCategory = selectedCategories[selectedCategories.length - 1];
let leafiestCategoryModels: Array<TtsModelListItem> = [];
if (leafiestCategory !== undefined) {
leafiestCategoryModels =
Array.from(
ttsModelsByCategoryToken.get(leafiestCategory.category_token) ||
new Set());
leafiestCategoryModels = Array.from(
ttsModelsByCategoryToken.get(leafiestCategory.category_token) || new Set()
);
} else {
leafiestCategoryModels = Array.from(new Set(allTtsModels));
}
@@ -65,16 +62,20 @@ export function ScopedVoiceModelOptions(props: Props) {
if (props.selectedTtsLanguageScope === "*") {
return true; // NB: Sentinel value of "*" means all languages.
}
return ttsModel.ietf_primary_language_subtag === props.selectedTtsLanguageScope;
return (
ttsModel.ietf_primary_language_subtag === props.selectedTtsLanguageScope
);
})
.map((ttsModel) => {
return {
label: ttsModel.title,
value: ttsModel.model_token,
}
};
});
let selectedOption = options.find((option) => option.value === maybeSelectedTtsModel?.model_token);
let selectedOption = options.find(
(option) => option.value === maybeSelectedTtsModel?.model_token
);
if (selectedOption === undefined && options.length > 0) {
// NB: We shouldn't select the first item in the list since that won't update the currently
@@ -84,9 +85,9 @@ export function ScopedVoiceModelOptions(props: Props) {
selectedOption = {
label: "Select voice...",
value: "*",
}
};
}
const voiceCount = options.length;
let isLoading = false;
@@ -101,27 +102,18 @@ export function ScopedVoiceModelOptions(props: Props) {
selectedOption = {
label: "Loading...",
value: "*",
}
};
} else if (options.length === 0) {
// NB: Perhaps the user has refined their search to be too narrow (langauge + category)
selectedOption = {
label: "No results (remove some filters)",
value: "*",
}
};
}
return (
<>
<div className="col">
<label className="sub-title">
<Trans
i18nKey="tts.TtsModelListPage.form.voicesLabel"
count={voiceCount}
>
Voice ({voiceCount} to choose from)
</Trans>
</label>
<div className="input-icon-search">
<span className="form-control-feedback">
<FontAwesomeIcon icon={faMicrophone} />
@@ -132,18 +124,20 @@ export function ScopedVoiceModelOptions(props: Props) {
options={options}
classNames={SearchFieldClass}
onChange={handleChange}
onMenuOpen={() => { Analytics.ttsOpenScopedVoiceSelectMenu() } }
onMenuOpen={() => {
Analytics.ttsOpenScopedVoiceSelectMenu();
}}
isLoading={isLoading}
// On mobile, we don't want the onscreen keyboard to take up half the UI.
autoFocus={false}
isSearchable={false}
// NB: The following settings improve upon performance.
// NB: The following settings improve upon performance.
// See: https://github.com/JedWatson/react-select/issues/3128
filterOption={createFilter({ignoreAccents: false})}
components={{Option: FastReactSelectOption} as any}
/>
filterOption={createFilter({ ignoreAccents: false })}
components={{ Option: FastReactSelectOption } as any}
/>
</div>
</div>
</>
)
);
}