Merge pull request #448 from storytold/bflat-fy-feature-mvp-search

feature/mvp search
This commit is contained in:
Brandon Thomas authored and GitHub committed 2024-01-11 15:46:45 -05:00
commit 411ed11292
11 files changed
+101 -167

No files matched your search

+4
View File
@@ -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 };
});
}
@@ -78,7 +78,7 @@ export default function AudioCard({
<Link
{...{
to: linkUrl,
state: { origin }
state: { origin },
}}
>
<Card padding={true} canHover={true}>
@@ -124,6 +124,9 @@ export default function AudioCard({
)}
<div>
/>
<LikeButton {...{
likeCount: data.likes,
...ratings.makeProps({
@@ -131,6 +134,7 @@ export default function AudioCard({
entityType: "media_file"
})
}} />
</div>
</div>
</>
@@ -139,7 +143,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">
@@ -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 (
@@ -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",
@@ -87,7 +87,6 @@ import VcModelDeletePage from "./pages/vc/vc_model_delete/VcModelDeletePage";
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 +379,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>
@@ -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>
);