Merge branch 'feature/mvp' of https://github.com/storytold/storyteller-frontend into feature/mvp

This commit is contained in:
Victor committed 2024-02-09 20:42:06 -08:00
commit 5efb004ad1
6 files changed
+225 -200

No files matched your search

@@ -19,7 +19,7 @@ interface ImageCardProps {
source?: string;
type: "media" | "weights";
inSelectModal?: boolean;
onResultSelect?: (data:{token: string, title:string}) => void;
onResultSelect?: (data: { token: string; title: string }) => void;
}
export default function ImageCard({
@@ -34,16 +34,16 @@ export default function ImageCard({
}: ImageCardProps) {
const history = useHistory();
// const { setToken, setWeightTitle } = useToken();
const linkUrl = getCardUrl(data,source,type);
const linkUrl = getCardUrl(data, source, type);
const handleSelectModalResultSelect = () => {
console.log("handleSelectModalResultSelect")
console.log("handleSelectModalResultSelect");
if (inSelectModal) {
onResultSelect && onResultSelect({
token: data.weight_token,
title: data.title
});
onResultSelect &&
onResultSelect({
token: data.weight_token,
title: data.title,
});
}
};
@@ -111,14 +111,16 @@ export default function ImageCard({
<div>
<p className="fs-7 opacity-75 mb-0">{timeAgo}</p>
</div>
<CardFooter {...{
creator: data?.maybe_creator,
entityToken: data.token,
entityType: "media_file",
makeBookmarksProps: bookmarks.makeProps,
makeRatingsProps: ratings.makeProps,
showCreator
}}/>
<CardFooter
{...{
creator: data?.maybe_creator,
entityToken: data.token,
entityType: "media_file",
makeBookmarksProps: bookmarks.makeProps,
makeRatingsProps: ratings.makeProps,
showCreator,
}}
/>
</div>
</div>
</>
@@ -169,14 +171,16 @@ export default function ImageCard({
<p className="fs-7 opacity-75 mb-0">{timeAgo}</p>
</div>
</div>
<CardFooter {...{
creator: data?.maybe_creator,
entityToken: data.weight_token,
entityType: "model_weight",
makeBookmarksProps: bookmarks.makeProps,
makeRatingsProps: ratings.makeProps,
showCreator
}}/>
<CardFooter
{...{
creator: data?.maybe_creator,
entityToken: data.weight_token,
entityType: "model_weight",
makeBookmarksProps: bookmarks.makeProps,
makeRatingsProps: ratings.makeProps,
showCreator,
}}
/>
</div>
</div>
</>
@@ -1,11 +1,11 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import { TempInput as Input } from 'components/common';
import { TempInput as Input } from "components/common";
// import Input from "../Input";
import { faSearch } from "@fortawesome/pro-solid-svg-icons";
import MasonryGrid from "../MasonryGrid/MasonryGrid";
import "./Searcher.scss";
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
import { useLazyLists } from "hooks";
import { useBookmarks, useLazyLists, useRatings } from "hooks";
import { SearchWeights } from "@storyteller/components/src/api/weights/SearchWeights";
import debounce from "lodash.debounce";
import WeightsCards from "../Card/WeightsCards";
@@ -18,7 +18,7 @@ interface SearcherProps {
type?: "page" | "modal";
dataType?: "media" | "weights";
weightType?: string;
onResultSelect?: (data:{token:string, title:string}) => void;
onResultSelect?: (data: { token: string; title: string }) => void;
searcherKey: string;
}
@@ -34,8 +34,8 @@ export default function Searcher({
const [foundWeights, setFoundWeights] = useState<Weight[]>([]);
const [isSearching, setIsSearching] = useState(false);
const [searchCompleted, setSearchCompleted] = useState(0);
// const bookmarks = useBookmarks();
// const ratings = useRatings();
const bookmarks = useBookmarks();
const ratings = useRatings();
const [list, listSet] = useState<Weight[]>([]);
useEffect(() => {
@@ -127,7 +127,6 @@ export default function Searcher({
foundWeights.map((data: any, key: number) => {
let props = {
data,
showCreator: true,
type: "weights",
inSelectModal: true,
onResultSelect,
@@ -185,6 +184,8 @@ export default function Searcher({
{weights.list.map((data: any, key: number) => {
let props = {
data,
ratings,
bookmarks,
showCreator: true,
type: "weights",
inSelectModal: true,
@@ -7,7 +7,7 @@ interface HeaderProps {
padding?: boolean;
}
const Header: React.FC<HeaderProps> = ({ children, padding }) => {
const headerClassName = `${padding ? "p-3 py-4 p-md-4" : ""}`.trim();
const headerClassName = `${padding ? "p-3 p-md-4 py-md-3" : ""}`.trim();
return <div className={headerClassName}>{children}</div>;
};
@@ -16,7 +16,7 @@ interface BodyProps {
padding?: boolean;
}
const Body: React.FC<BodyProps> = ({ children, padding }) => {
const bodyClassName = `${padding ? "p-3 py-4 p-md-4" : ""}`.trim();
const bodyClassName = `${padding ? "p-3 p-md-4" : ""}`.trim();
return <div className={bodyClassName}>{children}</div>;
};
@@ -25,7 +25,7 @@ interface FooterProps {
padding?: boolean;
}
const Footer: React.FC<FooterProps> = ({ children, padding }) => {
const footerClassName = `${padding ? "p-3 py-4 p-md-4" : ""}`.trim();
const footerClassName = `${padding ? "p-3 p-md-4" : ""}`.trim();
return <div className={footerClassName}>{children}</div>;
};
@@ -74,7 +74,7 @@ const SplitPanel: React.FC<PanelProps> & {
{body}
{dividerFooter && <hr className="m-0" />}
{footer}
{ <TintSpinner {...{ busy }} /> }
{<TintSpinner {...{ busy }} />}
</div>
);
};
@@ -9,6 +9,7 @@ interface Props {
title: React.ReactNode;
subText: React.ReactNode;
yOffset?: string;
extension?: React.ReactNode;
}
function PageHeaderWithImage(props: Props) {
@@ -31,6 +32,12 @@ function PageHeaderWithImage(props: Props) {
<p className="text-center text-md-start opacity-75">
{props.subText}
</p>
{props.extension && (
<div className="d-flex justify-content-center justify-content-md-start mt-3">
{props.extension}
</div>
)}
</div>
</div>
<div className="col-12 col-md-5 d-none d-md-block">
@@ -30,7 +30,7 @@ export default function TextToImagePage({
const hasImageGenJobs = inferenceJobs && inferenceJobs.length > 0;
if (!sessionWrapper.canAccessStudio()) {
return <StudioNotAvailable />
return <StudioNotAvailable />;
}
return (
@@ -40,7 +40,7 @@ export default function TextToImagePage({
titleIcon={faMessageImage}
title="Text to Image"
subText="Transform your thoughts into art."
yOffset="76%"
yOffset="68%"
/>
{hasImageGenJobs && (
@@ -5,9 +5,9 @@ import {
Input,
Label,
NumberSlider,
Panel,
SegmentButtons,
SelectModal,
SplitPanel,
TempSelect,
TempTextArea,
} from "components/common";
@@ -16,6 +16,7 @@ import {
faRectangleLandscape,
faRectanglePortrait,
faSquare,
faUpload,
} from "@fortawesome/pro-solid-svg-icons";
import { v4 as uuidv4 } from "uuid";
import {
@@ -278,7 +279,7 @@ function SdInferencePanel({
);
}
} else if (EnqueueImageGenIsError(response)) {
console.log("error",response);
console.log("error", response);
}
setIsEnqueuing(false);
@@ -293,186 +294,198 @@ function SdInferencePanel({
};
return (
<Panel padding={true}>
<h4 className="fw-semibold mb-4">Generate an Image</h4>
<div className="d-flex flex-column gap-3 mb-4">
{isStandalone && (
<SelectModal
required={true}
modalTitle="Select a Weight"
label="Select a Weight"
onSelect={handleOnWeightSelect}
tabs={[
{
label: "All Weights",
tabKey: "allWeights",
typeFilter: "sd_1.5",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedWeights",
typeFilter: "sd_1.5",
searcher: false,
type: "weights",
},
]}
/>
)}
<TempTextArea
{...{
label: "Prompt",
placeholder: "Enter a prompt",
onChange: handlePromptChange,
value: prompt,
required: true,
}}
/>
<TempTextArea
{...{
label: "Negative Prompt",
name: "negativePrompt",
placeholder: "Enter a negative prompt",
onChange: handleNegativePromptChange,
value: negativePrompt,
}}
/>
<SegmentButtons
{...{
label: "Aspect Ratio",
name: "aspectRatio",
onChange,
options: dimensionOpts,
value: aspectRatio,
}}
/>
</div>
<Accordion>
<Accordion.Item title="Advanced">
<div className="p-3 d-flex flex-column gap-3">
<div>
<label className="sub-title">Seed</label>
<div className="d-flex gap-2 align-items-center">
<SegmentButtons
{...{
name: "seed",
onChange: handleSeedChange,
options: seedOpts,
value: seed,
}}
/>
<Input
placeholder="Random"
value={seedNumber}
onChange={handleSeedNumberChange}
type="number"
onBlur={handleBlur}
/>
</div>
</div>
<TempSelect
{...{
label: "Sampler",
name: "sampler",
onChange,
options: samplerOpts,
value: sampler,
}}
/>
<NumberSlider
{...{
min: 1,
max: 30,
name: "cfgScale",
label: "CFG Scale",
onChange,
thumbTip: "CFG Scale",
value: cfgScale,
step: 0.5,
}}
/>
<NumberSlider
{...{
min: 8,
max: 64,
name: "samples",
label: "Samples",
onChange,
thumbTip: "Samples",
value: samples,
}}
<SplitPanel dividerHeader={true}>
<SplitPanel.Header padding={true}>
<div className="d-flex flex-wrap gap-2 align-items-center">
<h4 className="fw-semibold mb-0 flex-grow-1">Generate an Image</h4>
<div>
<Button
icon={faUpload}
label="Upload a Weight"
variant="secondary"
small={true}
to="/upload/sd"
/>
</div>
</div>
</SplitPanel.Header>
<SplitPanel.Body padding={true}>
<div className="d-flex flex-column gap-3 mb-4">
{isStandalone && (
<SelectModal
label="Additional LoRA Weight"
onSelect={handleOnSelect}
required={true}
modalTitle="Select a Weight"
label="Select a Weight"
onSelect={handleOnWeightSelect}
tabs={[
{
label: "All LoRA Weights",
tabKey: "allLoraWeights",
typeFilter: "loRA",
label: "All Weights",
tabKey: "allWeights",
typeFilter: "sd_1.5",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedLoraWeights",
typeFilter: "loRA",
tabKey: "bookmarkedWeights",
typeFilter: "sd_1.5",
searcher: false,
type: "weights",
},
]}
/>
)}
<div>
<Label label="Number of Generations" />
<PremiumLock
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
requiredPlan="pro"
>
<SegmentButtons
{...{
name: "batchCount",
onChange,
options: batchCountOpts,
value: batchCount,
}}
/>
</PremiumLock>
<TempTextArea
{...{
label: "Prompt",
placeholder: "Enter a prompt",
onChange: handlePromptChange,
value: prompt,
required: true,
}}
/>
<TempTextArea
{...{
label: "Negative Prompt",
name: "negativePrompt",
placeholder: "Enter a negative prompt",
onChange: handleNegativePromptChange,
value: negativePrompt,
}}
/>
<SegmentButtons
{...{
label: "Aspect Ratio",
name: "aspectRatio",
onChange,
options: dimensionOpts,
value: aspectRatio,
}}
/>
</div>
<Accordion>
<Accordion.Item title="Advanced">
<div className="p-3 d-flex flex-column gap-3">
<div>
<label className="sub-title">Seed</label>
<div className="d-flex gap-2 align-items-center">
<SegmentButtons
{...{
name: "seed",
onChange: handleSeedChange,
options: seedOpts,
value: seed,
}}
/>
<Input
placeholder="Random"
value={seedNumber}
onChange={handleSeedNumberChange}
type="number"
onBlur={handleBlur}
/>
</div>
</div>
<TempSelect
{...{
label: "Sampler",
name: "sampler",
onChange,
options: samplerOpts,
value: sampler,
}}
/>
<NumberSlider
{...{
min: 1,
max: 30,
name: "cfgScale",
label: "CFG Scale",
onChange,
thumbTip: "CFG Scale",
value: cfgScale,
step: 0.5,
}}
/>
<NumberSlider
{...{
min: 8,
max: 64,
name: "samples",
label: "Samples",
onChange,
thumbTip: "Samples",
value: samples,
}}
/>
<SelectModal
label="Additional LoRA Weight"
onSelect={handleOnSelect}
tabs={[
{
label: "All LoRA Weights",
tabKey: "allLoraWeights",
typeFilter: "loRA",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedLoraWeights",
typeFilter: "loRA",
searcher: false,
type: "weights",
},
]}
/>
<div>
<Label label="Number of Generations" />
<PremiumLock
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
requiredPlan="pro"
>
<SegmentButtons
{...{
name: "batchCount",
onChange,
options: batchCountOpts,
value: batchCount,
}}
/>
</PremiumLock>
</div>{" "}
</div>
</div>
</Accordion.Item>
</Accordion>
</Accordion.Item>
</Accordion>
<div className="d-flex gap-2 justify-content-end mt-4 mb-3">
<Button
{...{
label: "Clear All",
variant: "secondary",
onClick: resetToInitialState,
}}
/>
<Button
{...{
label: "Generate Image",
disabled: prompt === "" || weightToken === undefined,
onClick: handleEnqueueImageGen,
isLoading: isEnqueuing,
}}
/>
</div>
</SplitPanel.Body>
<div className="d-flex gap-2 justify-content-end mt-4 mb-3">
<Button
{...{
label: "Clear All",
variant: "secondary",
onClick: resetToInitialState,
}}
/>
<Button
{...{
label: "Generate Image",
disabled: prompt === "" || weightToken === undefined,
onClick: handleEnqueueImageGen,
isLoading: isEnqueuing,
}}
/>
</div>
<InferenceJobsList {...{
failures,
jobType: FrontendInferenceJobType.ImageGeneration
}} />
</Panel>
<InferenceJobsList
{...{
failures,
jobType: FrontendInferenceJobType.ImageGeneration,
}}
/>
</SplitPanel>
);
}