mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
Merge branch 'feature/mvp' of https://github.com/storytold/storyteller-frontend into feature/mvp
This commit is contained in:
commit
65012f285a
16 files changed
+318
-169
No files matched your search
@@ -132,6 +132,10 @@ class ApiConfig {
|
||||
return `${this.getApiOrigin()}/tts/search`;
|
||||
}
|
||||
|
||||
searchWeights(): string {
|
||||
return `${this.getApiOrigin()}/v1/weights/search`;
|
||||
}
|
||||
|
||||
getPendingTtsJobCount(): string {
|
||||
return `${this.getApiOrigin()}/tts/queue_length`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ApiConfig } from "../ApiConfig";
|
||||
import { Weight } from "./GetWeight";
|
||||
|
||||
export interface SearchWeightsRequest {
|
||||
search_term: string;
|
||||
}
|
||||
|
||||
export interface SearchWeightsResponse {
|
||||
success: boolean;
|
||||
weights: Weight[];
|
||||
}
|
||||
|
||||
export enum SearchWeightsError {
|
||||
NotFound,
|
||||
ServerError,
|
||||
FrontendError,
|
||||
}
|
||||
|
||||
export async function SearchWeights(
|
||||
request: SearchWeightsRequest
|
||||
): Promise<SearchWeightsResponse> {
|
||||
const endpoint = new ApiConfig().searchWeights();
|
||||
|
||||
return await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
credentials: "include",
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
if (res && "success" in res) {
|
||||
return res;
|
||||
} else {
|
||||
return { success: false };
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
return { success: false };
|
||||
});
|
||||
}
|
||||
@@ -60,9 +60,11 @@
|
||||
"react-dom": "^16.13.1",
|
||||
"react-drag-drop-files": "^2.3.9",
|
||||
"react-i18next": "^11.15.4",
|
||||
"react-iframe": "^1.8.5",
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-paginate": "^8.2.0",
|
||||
"react-range": "^1.8.14",
|
||||
"react-range-slider-input": "^3.0.7",
|
||||
"react-reveal": "^1.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "5.0.0",
|
||||
@@ -70,7 +72,6 @@
|
||||
"react-share": "^4.4.1",
|
||||
"react-twitch-embed": "^3.0.1",
|
||||
"react-wavesurfer.js": "^0.0.8",
|
||||
"react-range-slider-input": "^3.0.7",
|
||||
"sass": "^1.57.1",
|
||||
"typescript": "^3.7.5",
|
||||
"universal-cookie": "^6.1.1",
|
||||
|
||||
@@ -78,7 +78,7 @@ export default function AudioCard({
|
||||
<Link
|
||||
{...{
|
||||
to: linkUrl,
|
||||
state: { origin }
|
||||
state: { origin },
|
||||
}}
|
||||
>
|
||||
<Card padding={true} canHover={true}>
|
||||
@@ -124,6 +124,7 @@ export default function AudioCard({
|
||||
)}
|
||||
|
||||
<div>
|
||||
|
||||
<LikeButton {...{
|
||||
likeCount: data.likes,
|
||||
...ratings.makeProps({
|
||||
@@ -131,6 +132,7 @@ export default function AudioCard({
|
||||
entityType: "media_file"
|
||||
})
|
||||
}} />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
@@ -139,7 +141,9 @@ export default function AudioCard({
|
||||
{type === "weights" && (
|
||||
<>
|
||||
<div className="d-flex">
|
||||
{showCover && <WeightCoverImage src={coverImage} />}
|
||||
{showCover && (
|
||||
<WeightCoverImage src={coverImage} height={110} width={110} />
|
||||
)}
|
||||
|
||||
<div className="flex-grow-1">
|
||||
<div className="d-flex align-items-center">
|
||||
|
||||
+11
-8
@@ -8,10 +8,10 @@ import {
|
||||
faComment,
|
||||
faHeart,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { TtsModel } from "@storyteller/components/src/api/tts/SearchTtsModels";
|
||||
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
|
||||
interface Props {
|
||||
data: TtsModel[];
|
||||
data: Weight[];
|
||||
}
|
||||
|
||||
function shortenNumber(num: number): string {
|
||||
@@ -26,21 +26,24 @@ export default function ModelSearchResults(props: Props) {
|
||||
let likes = 1500;
|
||||
let uses = 25000;
|
||||
let comments = 25;
|
||||
let model_type = "Tacotron2";
|
||||
let model_type = "Tacotron2";
|
||||
|
||||
return (
|
||||
<div className="row g-3">
|
||||
{props.data.map((item) => {
|
||||
let modelPageLink = `/tts/${item.model_token}`;
|
||||
{props.data.map(item => {
|
||||
let modelPageLink = `/weight/${item.weight_token}`;
|
||||
|
||||
return (
|
||||
<div className="col-12 col-lg-6" key={item.model_token}>
|
||||
<div className="col-12 col-lg-6" key={item.weight_token}>
|
||||
<div className="model-search-results p-3">
|
||||
<h5 className="fw-semibold mb-0">{item.title}</h5>
|
||||
<p className="creator-name">
|
||||
by{" "}
|
||||
<Link className="fw-medium" to={`/profile/${item.creator_username}`}>
|
||||
{item.creator_display_name}
|
||||
<Link
|
||||
className="fw-medium"
|
||||
to={`/profile/${item.creator.username}`}
|
||||
>
|
||||
{item.creator.display_name}
|
||||
</Link>
|
||||
</p>
|
||||
<div className="d-flex align-items-end">
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import Button from "../Button";
|
||||
import { faSearch } from "@fortawesome/pro-solid-svg-icons";
|
||||
import {
|
||||
SearchTtsModels,
|
||||
TtsModel,
|
||||
} from "@storyteller/components/src/api/tts/SearchTtsModels";
|
||||
import { SearchWeights } from "@storyteller/components/src/api/weights/SearchWeights";
|
||||
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import SearchResultsDropdown from "./SearchResultsDropdown";
|
||||
import SearchField from "./SearchField";
|
||||
import "./SearchBar.scss";
|
||||
@@ -28,7 +26,7 @@ export default function SearchBar({
|
||||
let location = useLocation();
|
||||
|
||||
const { searchTerm, setSearchTerm } = useSearch();
|
||||
const [foundTtsModels, setFoundTtsModels] = useState<TtsModel[]>([]);
|
||||
const [foundWeights, setFoundWeights] = useState<Weight[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const isOnSearchPage = location.pathname.startsWith("/search");
|
||||
|
||||
@@ -47,18 +45,18 @@ export default function SearchBar({
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
let response = await SearchTtsModels(request);
|
||||
let response = await SearchWeights(request);
|
||||
|
||||
if (response.success) {
|
||||
let models = [...response.models];
|
||||
setFoundTtsModels(models);
|
||||
let weights = [...response.weights];
|
||||
setFoundWeights(weights);
|
||||
} else {
|
||||
setFoundTtsModels([]);
|
||||
setFoundWeights([]);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
},
|
||||
[setFoundTtsModels]
|
||||
[setFoundWeights]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -106,8 +104,8 @@ export default function SearchBar({
|
||||
/>
|
||||
{isFocused && !isOnSearchPage && (
|
||||
<SearchResultsDropdown
|
||||
data={foundTtsModels}
|
||||
isNoResults={foundTtsModels.length === 0 && searchTerm !== ""}
|
||||
data={foundWeights}
|
||||
isNoResults={foundWeights.length === 0 && searchTerm !== ""}
|
||||
isLoading={isLoading}
|
||||
searchTerm={searchTerm}
|
||||
/>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { TtsModel } from "@storyteller/components/src/api/tts/SearchTtsModels";
|
||||
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import React from "react";
|
||||
import { Link, useHistory } from "react-router-dom";
|
||||
import Badge from "../Badge";
|
||||
|
||||
interface SearchResultsDropdownProps {
|
||||
data: TtsModel[];
|
||||
data: Weight[];
|
||||
isNoResults?: boolean;
|
||||
isLoading?: boolean;
|
||||
searchTerm?: string;
|
||||
@@ -18,10 +18,10 @@ export default function SearchResultsDropdown({
|
||||
}: SearchResultsDropdownProps) {
|
||||
const history = useHistory();
|
||||
|
||||
const handleResultClick = (item: TtsModel, event: React.MouseEvent) => {
|
||||
const handleResultClick = (item: Weight, event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
history.push(`/weight/${item.model_token}`);
|
||||
history.push(`/weight/${item.weight_token}`);
|
||||
};
|
||||
|
||||
const handleInnerClick = (event: any) => {
|
||||
@@ -40,12 +40,12 @@ export default function SearchResultsDropdown({
|
||||
{data.length !== 0 && (
|
||||
<div className="search-results-dropdown">
|
||||
{data.map(item => {
|
||||
// let modelPageLink = `/weight/${item.model_token}`;
|
||||
// let modelPageLink = `/weight/${item.weight_token}`;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="search-results-dropdown-item p-3"
|
||||
key={item.model_token}
|
||||
key={item.weight_token}
|
||||
onClick={event => handleResultClick(item, event)}
|
||||
>
|
||||
<h6 className="fw-semibold mb-1">{item.title}</h6>
|
||||
@@ -54,10 +54,10 @@ export default function SearchResultsDropdown({
|
||||
by{" "}
|
||||
<Link
|
||||
className="fw-medium"
|
||||
to={`/profile/${item.creator_username}`}
|
||||
to={`/profile/${item.creator.username}`}
|
||||
onClick={handleInnerClick}
|
||||
>
|
||||
{item.creator_display_name}
|
||||
{item.creator.display_name}
|
||||
</Link>
|
||||
</p>
|
||||
<Badge label={"TTS"} color={"ultramarine"} small={true} />
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function WeightCoverImage({
|
||||
const containerStyle = {
|
||||
height: `${height}px`,
|
||||
width: `${width}px`,
|
||||
minWidth: `${width}px`,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
faCompass,
|
||||
faUser,
|
||||
faSignOutAlt,
|
||||
faCameraMovie,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import React, { useEffect, useState } from "react";
|
||||
@@ -353,6 +354,21 @@ export default function SideNav({
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<NavLink
|
||||
to="/storyteller-studio"
|
||||
activeClassName="active-link"
|
||||
onClick={handleNavLinkClick}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faCameraMovie}
|
||||
className="sidebar-heading-icon"
|
||||
/>
|
||||
Storyteller Studio
|
||||
{/* {t("videoStorytellerStudio")} */}
|
||||
</NavLink>
|
||||
</li>
|
||||
|
||||
<hr className="mb-3 mt-3" />
|
||||
<li className="sidebar-heading">{t("communityTitle")}</li>
|
||||
<li>
|
||||
|
||||
@@ -22,7 +22,7 @@ const weightTypeInfo: WeightTypeInfo = {
|
||||
color: "purple",
|
||||
fullLabel: "Stable Diffusion XL",
|
||||
},
|
||||
[WeightType.SVC]: { label: "SVC", color: "cyan", fullLabel: "SVC" },
|
||||
[WeightType.SVC]: { label: "SVC", color: "turquoise", fullLabel: "SVC" },
|
||||
[WeightType.LORA]: { label: "LoRA", color: "pink", fullLabel: "LoRA" },
|
||||
[WeightType.VALL_E]: {
|
||||
label: "VALL-E",
|
||||
|
||||
@@ -84,10 +84,10 @@ import { GenerateSpeechPage } from "./pages/generate_speech/GenerateSpeechPage";
|
||||
import VcModelViewPage from "./pages/vc/vc_model_view/VcModelViewPage";
|
||||
import VcModelEditPage from "./pages/vc/vc_model_edit/VcModelEditPage";
|
||||
import VcModelDeletePage from "./pages/vc/vc_model_delete/VcModelDeletePage";
|
||||
import { StorytellerStudioListPage } from "./pages/storyteller_studio/vc_model_list/StorytellerStudioListPage";
|
||||
import TopNav from "components/layout/TopNav/TopNav";
|
||||
import SideNav from "components/layout/SideNav/SideNav";
|
||||
import MobileMenu from "components/layout/MobileMenu/MobileMenu";
|
||||
import TtsModelSearchPage from "./pages/tts/tts_model_search/TtsModelSearchPage";
|
||||
import MediaPage from "./pages/media/MediaPage";
|
||||
import { VoiceDesignerFormPage } from "./pages/voice_designer/VoiceDesignerFormPage";
|
||||
import { VoiceDesignerMainPage } from "./pages/voice_designer/VoiceDesignerMainPage";
|
||||
@@ -380,12 +380,6 @@ class PageContainer extends React.Component<
|
||||
<SearchPage />
|
||||
</Route>
|
||||
|
||||
<Route path="/dev-tts">
|
||||
<TtsModelSearchPage
|
||||
sessionWrapper={this.props.sessionWrapper}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route path="/tts/result/:token/edit">
|
||||
<TtsResultEditPage sessionWrapper={this.props.sessionWrapper} />
|
||||
</Route>
|
||||
@@ -676,6 +670,15 @@ class PageContainer extends React.Component<
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route path="/storyteller-studio">
|
||||
<StorytellerStudioListPage
|
||||
sessionWrapper={this.props.sessionWrapper}
|
||||
sessionSubscriptionsWrapper={
|
||||
this.props.sessionSubscriptionsWrapper
|
||||
}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route path="/commissions">
|
||||
<CommunityCommissionsPage />
|
||||
</Route>
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import Iframe from "react-iframe";
|
||||
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import { SsPageHero } from "./components/SsPageHero";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
sessionSubscriptionsWrapper: SessionSubscriptionsWrapper;
|
||||
}
|
||||
|
||||
function StorytellerStudioListPage(props: Props) {
|
||||
return (
|
||||
<div>
|
||||
<SsPageHero
|
||||
sessionWrapper={props.sessionWrapper}
|
||||
sessionSubscriptionsWrapper={props.sessionSubscriptionsWrapper}
|
||||
/>
|
||||
|
||||
<div className="container mb-5">
|
||||
<Iframe
|
||||
url="https://engine.fakeyou.com?mode=studio"
|
||||
width="100%"
|
||||
height="900px"
|
||||
id=""
|
||||
className=""
|
||||
display="block"
|
||||
position="relative"
|
||||
/>
|
||||
{/* <div className="alert alert-info">
|
||||
<FontAwesomeIcon icon={faMoneyBill} className="me-2" />
|
||||
<span className="fw-medium">
|
||||
Get rewarded from our $15k prize pool for creating Voice to Voice
|
||||
models!
|
||||
</span>
|
||||
<Link to="/commissions" className="fw-semibold ms-2">
|
||||
See details <FontAwesomeIcon icon={faArrowRight} className="ms-1" />
|
||||
</Link>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const LoadingIcon: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<span
|
||||
className="spinner-border spinner-border-sm ms-3"
|
||||
role="status"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<span className="visually-hidden">Loading...</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { StorytellerStudioListPage };
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import { Link } from "react-router-dom";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faStar,
|
||||
faUser,
|
||||
faArrowRight,
|
||||
faMicrophoneStand,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Analytics } from "../../../../../../common/Analytics";
|
||||
import { WebUrl } from "../../../../../../common/WebUrl";
|
||||
import { PageHeaderWithImage } from "../../../../_common/PageHeaderWithImage";
|
||||
import { useLocalize } from "hooks";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
sessionSubscriptionsWrapper: SessionSubscriptionsWrapper;
|
||||
}
|
||||
|
||||
export function SsPageHero(props: Props) {
|
||||
const { t } = useLocalize("VcModelListPage");
|
||||
const randomImage = useMemo(() => {
|
||||
const images = ["mascot/may4th.webp"];
|
||||
|
||||
return images[Math.floor(Math.random() * images.length)];
|
||||
}, []);
|
||||
|
||||
let signUpButton = <></>;
|
||||
let viewPricingButton = <></>;
|
||||
let upgradeButton = <></>;
|
||||
let myProfileButton = <></>;
|
||||
|
||||
if (!props.sessionWrapper.isLoggedIn()) {
|
||||
signUpButton = (
|
||||
<>
|
||||
<Link
|
||||
to="/signup"
|
||||
onClick={() => {
|
||||
Analytics.ttsClickHeroSignup();
|
||||
}}
|
||||
>
|
||||
<button type="button" className="btn btn-primary w-100">
|
||||
{t("heroButtonSignUp")}
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-2" />
|
||||
</button>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
viewPricingButton = (
|
||||
<>
|
||||
<Link
|
||||
to={WebUrl.pricingPageWithReferer("tts_hero_new")}
|
||||
onClick={() => {
|
||||
Analytics.ttsClickHeroViewPricing();
|
||||
}}
|
||||
>
|
||||
<button type="button" className="btn btn-secondary w-100">
|
||||
<FontAwesomeIcon icon={faStar} className="me-2" />
|
||||
{t("heroButtonPricing")}
|
||||
</button>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (props.sessionWrapper.isLoggedIn()) {
|
||||
let displayName = props.sessionWrapper.getDisplayName() as string; // NB: If logged in, should be string
|
||||
let url = WebUrl.userProfilePage(displayName);
|
||||
myProfileButton = (
|
||||
<>
|
||||
<Link
|
||||
to={url}
|
||||
onClick={() => {
|
||||
Analytics.ttsClickHeroViewProfile();
|
||||
}}
|
||||
>
|
||||
<button type="button" className="btn btn-secondary w-100">
|
||||
<FontAwesomeIcon icon={faUser} className="me-2" />
|
||||
{t("heroButtonProfile")}
|
||||
</button>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
if (!props.sessionSubscriptionsWrapper.hasPaidFeatures()) {
|
||||
upgradeButton = (
|
||||
<>
|
||||
<Link
|
||||
to={WebUrl.pricingPageWithReferer("tts_hero_user")}
|
||||
onClick={() => {
|
||||
Analytics.ttsClickHeroUpgradePlan();
|
||||
}}
|
||||
>
|
||||
<button type="button" className="btn btn-primary w-100">
|
||||
<FontAwesomeIcon icon={faStar} className="me-2" />
|
||||
{t("heroButtonUpgradePlan")}
|
||||
</button>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const titleIcon = (
|
||||
<FontAwesomeIcon icon={faMicrophoneStand} className="me-3 me-lg-4" />
|
||||
);
|
||||
const title = <>Storyteller Studio</>;
|
||||
const subText = <>Anyone can make films.</>;
|
||||
const actionButtons = (
|
||||
<>
|
||||
{upgradeButton}
|
||||
{signUpButton}
|
||||
{viewPricingButton}
|
||||
{myProfileButton}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeaderWithImage
|
||||
headerImage={randomImage}
|
||||
titleIcon={titleIcon}
|
||||
title={title}
|
||||
subText={subText}
|
||||
showButtons={true}
|
||||
actionButtons={actionButtons}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import Container from "components/common/Container";
|
||||
import PageHeader from "components/layout/PageHeader";
|
||||
import { faClock, faMessageDots } from "@fortawesome/pro-solid-svg-icons";
|
||||
import ModelSearch from "components/common/ModelSearch";
|
||||
import Panel from "components/common/Panel";
|
||||
import ModelSearchResults from "components/common/ModelSearchResults";
|
||||
import ModelTags from "components/common/ModelTags";
|
||||
import Select from "components/common/Select";
|
||||
import { SearchTtsModels, TtsModel } from "@storyteller/components/src/api/tts/SearchTtsModels";
|
||||
|
||||
interface TtsModelSearchPageProps {
|
||||
sessionWrapper: SessionWrapper;
|
||||
}
|
||||
|
||||
const allTags = [
|
||||
"English",
|
||||
"Spanish",
|
||||
"Portuguese",
|
||||
"High-pitched",
|
||||
"Low-pitched",
|
||||
"Character",
|
||||
];
|
||||
|
||||
export default function TtsModelSearchPage(props: TtsModelSearchPageProps) {
|
||||
const [searchTerm, setSearchTerm] = useState<string>("");
|
||||
const [foundTtsModels, setFoundTtsModels] = useState<TtsModel[]>([]);
|
||||
|
||||
let selectedTags : any = [];
|
||||
let handleSelectTag = () => {};
|
||||
|
||||
const maybeSearch = useCallback(async (
|
||||
value: string
|
||||
) => {
|
||||
setSearchTerm(value);
|
||||
}, []);
|
||||
|
||||
|
||||
const doSearch = useCallback(async (
|
||||
value: string
|
||||
) => {
|
||||
let request = {
|
||||
search_term: value,
|
||||
}
|
||||
|
||||
let response = await SearchTtsModels(request);
|
||||
|
||||
if (response.success) {
|
||||
let models = [...response.models];
|
||||
setFoundTtsModels(models);
|
||||
} else {
|
||||
setFoundTtsModels([]);
|
||||
}
|
||||
}, [setFoundTtsModels]);
|
||||
|
||||
useEffect(() => {
|
||||
doSearch(searchTerm);
|
||||
}, [doSearch, searchTerm])
|
||||
|
||||
const searchTts = (
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<ModelSearch value={searchTerm} onChange={maybeSearch} />
|
||||
<ModelTags
|
||||
tags={allTags}
|
||||
selectedTags={selectedTags}
|
||||
onSelectTag={handleSelectTag}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
const sortOptions = [
|
||||
{ value: "most liked", label: "Most Liked" },
|
||||
{ value: "most used", label: "Most Used" },
|
||||
{ value: "moset recent", label: "Most Recent" },
|
||||
];
|
||||
const sortTimeOptions = [
|
||||
{ value: "all time", label: "All Time" },
|
||||
{ value: "today", label: "Today" },
|
||||
{ value: "this week", label: "This Week" },
|
||||
{ value: "this month", label: "This Month" },
|
||||
];
|
||||
|
||||
return (
|
||||
<Container type="panel">
|
||||
<PageHeader
|
||||
title="Text to Speech"
|
||||
titleIcon={faMessageDots}
|
||||
subText="Turn text into your favorite character's voice."
|
||||
// showButton={true}
|
||||
// buttonLabel="Create a voice"
|
||||
// buttonVariant="secondary"
|
||||
// buttonTo="/voice-designer"
|
||||
extension={searchTts}
|
||||
panel={false}
|
||||
/>
|
||||
<Panel padding={true}>
|
||||
<div className="d-flex gap-2 mb-4">
|
||||
<Select
|
||||
small={true}
|
||||
options={sortOptions}
|
||||
defaultValue={sortOptions[0]}
|
||||
/>
|
||||
<Select
|
||||
small={true}
|
||||
icon={faClock}
|
||||
options={sortTimeOptions}
|
||||
defaultValue={sortTimeOptions[0]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/*<ModelSearchResults data={filteredData} />*/}
|
||||
<ModelSearchResults data={foundTtsModels} />
|
||||
</Panel>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -6,10 +6,8 @@ import Panel from "components/common/Panel";
|
||||
import ModelSearchResults from "components/common/ModelSearchResults";
|
||||
import ModelTags from "components/common/ModelTags";
|
||||
import Select from "components/common/Select";
|
||||
import {
|
||||
SearchTtsModels,
|
||||
TtsModel,
|
||||
} from "@storyteller/components/src/api/tts/SearchTtsModels";
|
||||
import { SearchWeights } from "@storyteller/components/src/api/weights/SearchWeights";
|
||||
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
const allTags = [
|
||||
@@ -22,7 +20,7 @@ const allTags = [
|
||||
];
|
||||
|
||||
export default function SearchPage() {
|
||||
const [foundTtsModels, setFoundTtsModels] = useState<TtsModel[]>([]);
|
||||
const [foundWeights, setFoundWeights] = useState<Weight[]>([]);
|
||||
|
||||
const useQuery = () => {
|
||||
return new URLSearchParams(useLocation().search);
|
||||
@@ -34,16 +32,16 @@ export default function SearchPage() {
|
||||
search_term: value,
|
||||
};
|
||||
|
||||
let response = await SearchTtsModels(request);
|
||||
let response = await SearchWeights(request);
|
||||
|
||||
if (response.success) {
|
||||
let models = [...response.models];
|
||||
setFoundTtsModels(models);
|
||||
let weights = [...response.weights];
|
||||
setFoundWeights(weights);
|
||||
} else {
|
||||
setFoundTtsModels([]);
|
||||
setFoundWeights([]);
|
||||
}
|
||||
},
|
||||
[setFoundTtsModels]
|
||||
[setFoundWeights]
|
||||
);
|
||||
|
||||
const query = useQuery();
|
||||
@@ -83,7 +81,7 @@ export default function SearchPage() {
|
||||
return (
|
||||
<Container type="panel" className="mb-5">
|
||||
<PageHeader
|
||||
title={`${foundTtsModels.length || "0"} results for "${urlSearchTerm}"`}
|
||||
title={`${foundWeights.length || "0"} results for "${urlSearchTerm}"`}
|
||||
titleH2={true}
|
||||
extension={tags}
|
||||
panel={false}
|
||||
@@ -104,7 +102,7 @@ export default function SearchPage() {
|
||||
</div>
|
||||
|
||||
{/*<ModelSearchResults data={filteredData} />*/}
|
||||
<ModelSearchResults data={foundTtsModels} />
|
||||
<ModelSearchResults data={foundWeights} />
|
||||
</Panel>
|
||||
</Container>
|
||||
);
|
||||
|
||||
@@ -4472,6 +4472,7 @@ __metadata:
|
||||
react-infinite-scroll-component: ^6.1.0
|
||||
react-paginate: ^8.2.0
|
||||
react-range: ^1.8.14
|
||||
react-range-slider-input: ^3.0.7
|
||||
react-reveal: ^1.2.2
|
||||
react-router-dom: ^5.2.0
|
||||
react-scripts: 5.0.0
|
||||
@@ -4591,7 +4592,6 @@ __metadata:
|
||||
moment: ^2.29.4
|
||||
prettier: ^3.1.0
|
||||
pretty-quick: ^3.1.3
|
||||
react-range-slider-input: ^3.0.7
|
||||
universal-cookie: ^6.1.1
|
||||
yarn: ^1.22.19
|
||||
languageName: unknown
|
||||
|
||||
Reference in new issue
Block a user