mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-12 04:42:16 +00:00
UploadSDWeightPage wired up
This commit is contained in:
1 parent
78037d5448
commit
ad29d720d7
11 files changed
+200
-59
No files matched your search
@@ -0,0 +1,22 @@
|
||||
import MakeRequest from "../MakeRequest";
|
||||
|
||||
export interface UploadModelRequest {
|
||||
uuid_idempotency_token: String,
|
||||
type_of_inference: String, // upload_lora / check_point / inference
|
||||
maybe_upload_path?: String,
|
||||
maybe_lora_upload_path?: String,
|
||||
title: String,
|
||||
visibility: String,
|
||||
description: String
|
||||
}
|
||||
|
||||
export interface UploadModelResponse {
|
||||
success: boolean,
|
||||
maybe_sd_model_token?: String,
|
||||
maybe_lora_model_token?: String,
|
||||
}
|
||||
|
||||
export const UploadModel = MakeRequest<string, UploadModelRequest, UploadModelResponse,{}>({
|
||||
method: "POST",
|
||||
routingFunction: () => "/v1/image_gen/model/upload",
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
.fy-cover-img-input {
|
||||
// background-color: red;
|
||||
position: relative;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
|
||||
.fy-cover-control {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.upload-control-btn {
|
||||
background-color: rgba($secondary, 0.8);
|
||||
backdrop-filter: blur(2px);
|
||||
border: none;
|
||||
margin: auto auto 1rem auto;
|
||||
}
|
||||
|
||||
.weight-initial-cover-img {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: 0.5rem;
|
||||
position: absolute;
|
||||
// display: flex;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
// padding-bottom: 100%;
|
||||
|
||||
div {
|
||||
// background-color: red;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,23 +40,25 @@ export default function CoverImageInput({ currentPath, onClick, status, ...rest
|
||||
const [editingImg, editingImgSet] = useState(0);
|
||||
const transitions = useTransition(editingImg, basicTransition({}));
|
||||
|
||||
return transitions((style, i) => !currentPath || i ? <a.div {...{ style }}>
|
||||
<ImageInput {...{ ...rest, disabled: status > 1, placeholderIcon: faImage }} >
|
||||
<div {...{ className: "fy-cover-control" }}>
|
||||
<UploadControl {...{ onClick, status }} />
|
||||
return <div {...{ className: "fy-cover-img-input" }}>
|
||||
{ transitions((style, i) => !currentPath || i ? <a.div {...{ style }}>
|
||||
<ImageInput {...{ ...rest, disabled: status > 1, placeholderIcon: faImage }} >
|
||||
<div {...{ className: "fy-cover-control" }}>
|
||||
<UploadControl {...{ onClick, status }} />
|
||||
</div>
|
||||
</ImageInput>
|
||||
</a.div> : <a.div {...{
|
||||
className: "weight-initial-cover-img",
|
||||
style: { ...style, backgroundImage: `url(${ currentPath })` }
|
||||
}}>
|
||||
<div>
|
||||
<Button {...{
|
||||
className: "upload-control-btn",
|
||||
label: "Change cover image",
|
||||
onClick: () => editingImgSet(1),
|
||||
variant: "secondary"
|
||||
}} />
|
||||
</div>
|
||||
</ImageInput>
|
||||
</a.div> : <a.div {...{
|
||||
className: "weight-initial-cover-img",
|
||||
style: { ...style, backgroundImage: `url(${ currentPath })` }
|
||||
}}>
|
||||
<div>
|
||||
<Button {...{
|
||||
className: "upload-control-btn",
|
||||
label: "Change cover image",
|
||||
onClick: () => editingImgSet(1),
|
||||
variant: "secondary"
|
||||
}} />
|
||||
</div>
|
||||
</a.div>);
|
||||
</a.div> )}
|
||||
</div>;
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import useBookmarks from './useBookmarks';
|
||||
import useCoverImgUpload from './useCoverImgUpload';
|
||||
import useFile from './useFile';
|
||||
import useHover from './useHover';
|
||||
import useId from './useId';
|
||||
@@ -10,12 +11,14 @@ import useListContent from './useListContent';
|
||||
import useLocalize from './useLocalize';
|
||||
import useMedia from './useMedia';
|
||||
import useRatings from './useRatings';
|
||||
import useSdUpload from './useSdUpload';
|
||||
import useSession from './useSession';
|
||||
import useVideo from './useVideo';
|
||||
import useWeightFetch from './useWeightFetch';
|
||||
|
||||
export {
|
||||
useBookmarks,
|
||||
useCoverImgUpload,
|
||||
useFile,
|
||||
useHover,
|
||||
useId,
|
||||
@@ -27,6 +30,7 @@ export {
|
||||
useLocalize,
|
||||
useMedia,
|
||||
useRatings,
|
||||
useSdUpload,
|
||||
useSession,
|
||||
useVideo,
|
||||
useWeightFetch
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./useCoverImgUpload";
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useState } from 'react';
|
||||
import { UploadMedia, UploadMediaResponse } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useFile } from "hooks";
|
||||
|
||||
|
||||
export default function useCoverImgUpload() {
|
||||
const fileProps = useFile({});
|
||||
const [token, tokenSet] = useState("");
|
||||
const [status, statusSet] = useState(FetchStatus.ready);
|
||||
|
||||
const upload = (e: any) => {
|
||||
if (fileProps.file && status < 2) {
|
||||
statusSet(FetchStatus.in_progress);
|
||||
UploadMedia({
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file: fileProps.file,
|
||||
source: "file",
|
||||
}) // if there an audio file it uploads here
|
||||
.then((res: UploadMediaResponse) => {
|
||||
if ("media_file_token" in res) {
|
||||
statusSet(FetchStatus.success);
|
||||
tokenSet(res.media_file_token);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return { fileProps, status, token, upload };
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./useSdUpload";
|
||||
@@ -0,0 +1,52 @@
|
||||
import { useState } from 'react';
|
||||
import { UploadModel } from "@storyteller/components/src/api/image_generation/UploadModel";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import { useCoverImgUpload } from "hooks";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
// interface Props {
|
||||
// value?: any;
|
||||
// }
|
||||
|
||||
// this hook is mostly for organizational purposes while I work -V
|
||||
|
||||
export default function useSdUpload() {
|
||||
const [title, titleSet] = useState("");
|
||||
const [uploadPath,uploadPathSet] = useState("");
|
||||
const [visibility, visibilitySet] = useState("public");
|
||||
const [descriptionMD, descriptionMDSet] = useState("");
|
||||
const [writeStatus, writeStatusSet] = useState(FetchStatus.paused);
|
||||
const coverImg = useCoverImgUpload();
|
||||
|
||||
const onChange = ({ target }: { target: { name: string; value: any } }) => {
|
||||
const todo: { [key: string]: (x: any) => void } = {
|
||||
descriptionMDSet,
|
||||
uploadPathSet,
|
||||
titleSet,
|
||||
visibilitySet
|
||||
};
|
||||
todo[target.name + "Set"](target.value);
|
||||
};
|
||||
|
||||
const upload = () => {
|
||||
writeStatusSet(FetchStatus.in_progress);
|
||||
UploadModel("",{
|
||||
...coverImg.token ? { cover_image_media_file_token: coverImg.token } : {},
|
||||
description: descriptionMD,
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
type_of_inference: "inference",
|
||||
maybe_upload_path: uploadPath,
|
||||
title,
|
||||
visibility
|
||||
})
|
||||
.then((res: any) => {
|
||||
writeStatusSet(FetchStatus.success);
|
||||
console.log("🌠",res);
|
||||
// history.replace(`/weight/${token}`);
|
||||
})
|
||||
.catch(err => {
|
||||
writeStatusSet(FetchStatus.error);
|
||||
});
|
||||
}
|
||||
return { coverImg, descriptionMD, onChange, title, upload, uploadPath, visibility, writeStatus };
|
||||
};
|
||||
@@ -1,15 +1,10 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import {
|
||||
GetWeight,
|
||||
Weight,
|
||||
} from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import { GetWeight, Weight } from "@storyteller/components/src/api/weights/GetWeight";
|
||||
import { UpdateWeight } from "@storyteller/components/src/api/weights/UpdateWeight";
|
||||
import { DeleteWeight } from "@storyteller/components/src/api/weights/DeleteWeight";
|
||||
import { UploadMedia, UploadMediaResponse } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { useFile } from "hooks";
|
||||
import { useCoverImgUpload } from "hooks";
|
||||
|
||||
interface Props {
|
||||
onRemove?: (x: any) => void;
|
||||
@@ -23,12 +18,10 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
const [title, titleSet] = useState("");
|
||||
const [visibility, visibilitySet] = useState("public");
|
||||
const [descriptionMD, descriptionMDSet] = useState("");
|
||||
const [imgMediaFile, imgMediaFileSet] = useState("");
|
||||
const [imgUploadStatus, imgUploadStatusSet] = useState(FetchStatus.ready);
|
||||
const imageProps = useFile({});
|
||||
const isLoading = status === FetchStatus.ready || status === FetchStatus.in_progress;
|
||||
const fetchError = status === FetchStatus.error;
|
||||
const history = useHistory();
|
||||
const coverImg = useCoverImgUpload();
|
||||
|
||||
const onChange = ({ target }: { target: { name: string; value: any } }) => {
|
||||
const todo: { [key: string]: (x: any) => void } = {
|
||||
@@ -42,7 +35,7 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
const update = () => {
|
||||
writeStatusSet(FetchStatus.in_progress);
|
||||
UpdateWeight(token,{
|
||||
...imgMediaFile ? { cover_image_media_file_token: imgMediaFile } : {},
|
||||
...coverImg.token ? { cover_image_media_file_token: coverImg.token } : {},
|
||||
description_markdown: descriptionMD,
|
||||
description_rendered_html: data?.description_rendered_html || "",
|
||||
title,
|
||||
@@ -69,23 +62,6 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
onRemove(res);
|
||||
});
|
||||
};
|
||||
|
||||
const uploadCoverImg = (e: any) => {
|
||||
if (imageProps.file && imgUploadStatus < 2) {
|
||||
imgUploadStatusSet(FetchStatus.in_progress);
|
||||
UploadMedia({
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file: imageProps.file,
|
||||
source: "file",
|
||||
}) // if there an audio file it uploads here
|
||||
.then((res: UploadMediaResponse) => {
|
||||
if ("media_file_token" in res) {
|
||||
imgUploadStatusSet(FetchStatus.success);
|
||||
imgMediaFileSet(res.media_file_token);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (token && !data && status === FetchStatus.ready) {
|
||||
@@ -109,5 +85,5 @@ export default function useWeightFetch({ onRemove = () => {}, token }: Props) {
|
||||
}
|
||||
}, [status, token, data]);
|
||||
|
||||
return { data, fetchError, imgMediaFile, imgMediaFileSet, imageProps, imgUploadStatus, isLoading, descriptionMD, onChange, remove, status, title, update, uploadCoverImg, visibility, writeStatus };
|
||||
return { coverImg, data, fetchError, isLoading, descriptionMD, onChange, remove, status, title, update, visibility, writeStatus };
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import PageHeader from "components/layout/PageHeader";
|
||||
import {
|
||||
Button,
|
||||
Container,
|
||||
CoverImageInput,
|
||||
Panel,
|
||||
Skeleton,
|
||||
SplitPanel,
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
TempTextArea,
|
||||
} from "components/common";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { useSdUpload } from "hooks";
|
||||
|
||||
interface UploadSdWeightPageProps {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -34,6 +36,8 @@ export default function UploadSdWeightPage({
|
||||
{ label: "Private", value: "private" },
|
||||
];
|
||||
|
||||
const { coverImg, descriptionMD, onChange, title, upload, uploadPath, visibility } = useSdUpload();
|
||||
|
||||
if (!sessionWrapper.isLoggedIn() && !isLoading) {
|
||||
return (
|
||||
<Container type="panel">
|
||||
@@ -85,13 +89,21 @@ export default function UploadSdWeightPage({
|
||||
<div className="row gx-4 gy-3">
|
||||
<div className="col-12 col-lg-5">
|
||||
<label className="sub-title required">Cover Image</label>
|
||||
<CoverImageInput {...{
|
||||
currentPath: "",
|
||||
onClick: coverImg.upload,
|
||||
status: coverImg.status,
|
||||
...coverImg.fileProps
|
||||
}} />
|
||||
</div>
|
||||
<div className="col-12 col-lg-7 order-first order-lg-last">
|
||||
<TempInput
|
||||
{...{
|
||||
label: "Title",
|
||||
name: "title",
|
||||
onChange,
|
||||
placeholder: "Title",
|
||||
value: title,
|
||||
required: true,
|
||||
}}
|
||||
/>
|
||||
@@ -99,8 +111,10 @@ export default function UploadSdWeightPage({
|
||||
<TempInput
|
||||
{...{
|
||||
label: "Download URL, eg. Google Drive link",
|
||||
name: "Url",
|
||||
name: "uploadPath",
|
||||
onChange,
|
||||
placeholder: "Download URL",
|
||||
value: uploadPath,
|
||||
required: true,
|
||||
}}
|
||||
/>
|
||||
@@ -110,15 +124,19 @@ export default function UploadSdWeightPage({
|
||||
icon: faEye,
|
||||
label: "Visibility",
|
||||
name: "visibility",
|
||||
onChange,
|
||||
options: visibilityOptions,
|
||||
placeholder: "Voice name",
|
||||
value: visibility,
|
||||
}}
|
||||
/>
|
||||
<TempTextArea
|
||||
{...{
|
||||
label: "Description",
|
||||
name: "descriptionMD",
|
||||
onChange,
|
||||
placeholder: "Description",
|
||||
value: descriptionMD,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -129,6 +147,7 @@ export default function UploadSdWeightPage({
|
||||
<Button
|
||||
{...{
|
||||
label: "Upload Weight",
|
||||
onClick: upload
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -37,16 +37,14 @@ export default function WeightEditPage({
|
||||
const [weightCreatorToken] = useState("");
|
||||
|
||||
const {
|
||||
coverImg,
|
||||
data: weight,
|
||||
descriptionMD,
|
||||
// fetchError,
|
||||
// imgMediaFile,
|
||||
imageProps,
|
||||
imgUploadStatus,
|
||||
isLoading,
|
||||
onChange,
|
||||
title,
|
||||
uploadCoverImg,
|
||||
update,
|
||||
visibility,
|
||||
writeStatus
|
||||
@@ -119,14 +117,12 @@ export default function WeightEditPage({
|
||||
<div {...{ className: "weight-editor row gy-3 gx-4" }}>
|
||||
<div {...{ className: "col-12 col-lg-5" }}>
|
||||
<label className="sub-title">Cover Image</label>
|
||||
<div {...{ className: "fy-cover-img-input" }}>
|
||||
<CoverImageInput {...{
|
||||
currentPath,
|
||||
onClick: uploadCoverImg,
|
||||
status: imgUploadStatus,
|
||||
...imageProps
|
||||
}} />
|
||||
</div>
|
||||
<CoverImageInput {...{
|
||||
currentPath,
|
||||
onClick: coverImg.upload,
|
||||
status: coverImg.status,
|
||||
...coverImg.fileProps
|
||||
}} />
|
||||
</div>
|
||||
<div {...{ className: "col-lg-7 order-first order-lg-last" }}>
|
||||
<TempInput
|
||||
|
||||
Reference in new issue
Block a user