weight card revision/type consolidation

This commit is contained in:
Victor committed 2024-02-06 23:26:39 -08:00
1 parent c0c98b4e35
commit 34849ab4ef
13 files changed
+137 -75

No files matched your search

@@ -14,24 +14,14 @@ export default function Label({
required,
disabled,
}: Props) {
return (
<div
{...{
className: `fy-input-label ${disabled ? "opacity-50" : ""}`.trim(),
}}
>
{label ? (
<label
{...{ className: `fw-medium ${required ? " required" : ""}`.trim() }}
>
{label}
</label>
) : null}
{invalidReason ? (
<span {...{ className: "label-error form-text red is-danger" }}>
{invalidReason}
</span>
) : null}
</div>
);
return label ? <div {...{ className: `fy-input-label${disabled ? "opacity-50" : "" }` }}>
<label {...{ className: `fw-medium${required ? " required" : "" }` }} >
{label}
</label>
{ invalidReason ? (
<span {...{ className: "label-error form-text red is-danger" }}>
{invalidReason}
</span>
) : null }
</div> : null;
}
@@ -106,4 +106,14 @@
label { }
}
.fy-entity-input-upload-detail {
span {
opacity: .66;
display: block;
font-size: .75rem;
line-height: 1em;
height: .75rem;
}
}
}
@@ -8,7 +8,7 @@ import { FileWrapper, Label, Spinner } from "components/common";
import { EntityType, MediaFilterProp, WeightFilterProp } from "components/entities/EntityTypes";
import { useFile, useMedia, useModal, useSession } from "hooks";
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
import { faFileArrowUp, faGrid, faPersonWalking } from "@fortawesome/pro-solid-svg-icons";
import { faDiagramSankey, faFile, faFileArrowUp, faGrid, faImage, faPersonWalking, faWaveform } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon as Icon } from "@fortawesome/react-fontawesome";
import { UploadMedia, UploadMediaResponse } from "@storyteller/components/src/api/media_files/UploadMedia";
import { v4 as uuidv4 } from "uuid";
@@ -17,6 +17,7 @@ import "./EntityInput.scss";
interface Props {
label?: string,
onChange?: any,
owner?: string,
mediaType?: MediaFilterProp,
aspectRatio?: "square" | "landscape" | "portrait",
weightType?: WeightFilterProp,
@@ -32,6 +33,7 @@ interface EmptySlideProps extends SlideProps {
inputProps?: any,
onSelect: any,
open: any,
owner: string,
user: any
};
@@ -64,24 +66,37 @@ const MocapInputFull = ({ media }: SlideProps) => {
</>;
};
const MediaPickerEmpty = ({ entityType, filterType, media, onSelect, open, inputProps, user }: EmptySlideProps) => {
const MediaPickerEmpty = ({ entityType, filterType, media, onSelect, open, owner, inputProps, user }: EmptySlideProps) => {
const browserClick = () => open({
component: MediaBrowser,
props: { entityType, filterType, onSelect, username: user?.username || "" }
props: { entityType, filterType, onSelect, owner, username: user?.username || "" }
});
const mediaIcons = () => {
switch (filterType) {
case "audio": return faWaveform;
case "image": return faImage;
case "bvh": return faPersonWalking;
default: return faFile;
}
}
return <>
<Icon {...{ className: "fy-entity-input-icon", icon: faPersonWalking }}/>
<Icon {...{ className: "fy-entity-input-icon", icon: [faFile,mediaIcons(),faDiagramSankey][entityType] }}/>
<div {...{ className: "fy-entity-input-empty-controls" }}>
<FileWrapper {...{ containerClass: "fy-entity-input-row", panelClass: "fy-entity-input-button", noStyle: true, ...inputProps }}>
<>
<Icon {...{ className: "fy-entity-input-label-icon", icon: faFileArrowUp }}/>
Upload, click or drag here
</>
</FileWrapper>
{ entityType === EntityType.media &&
<FileWrapper {...{ containerClass: "fy-entity-input-row", panelClass: "fy-entity-input-button", noStyle: true, ...inputProps }}>
<>
<Icon {...{ className: "fy-entity-input-label-icon", icon: faFileArrowUp }}/>
<div {...{ className: "fy-entity-input-upload-detail" }}>
Upload, click or drag here
{ filterType !== "all" && <span>{ filterType } files supported</span> }
</div>
</>
</FileWrapper> }
<div {...{ className: "fy-entity-input-row fy-entity-input-button", onClick: browserClick }}>
<Icon {...{ className: "fy-entity-input-label-icon", icon: faGrid }}/>
Choose from your media
Choose from your { ["","media","weights"][entityType] }
</div>
</div>
</>;
@@ -94,7 +109,7 @@ const AniMod = ({ animating, className, isLeaving, render: Render, style, ...res
<Render {...{ ...rest, animating }} />
</a.div>;
export default function EntityInput({ aspectRatio = "square", label, onChange, mediaType, weightType }: Props) {
export default function EntityInput({ aspectRatio = "square", label, onChange, owner, mediaType, weightType }: Props) {
const entityType = mediaType ? EntityType.media : weightType ? EntityType.weights : EntityType.unknown;
const filterType = mediaType || weightType || "all";
const { search } = useLocation();
@@ -149,7 +164,7 @@ export default function EntityInput({ aspectRatio = "square", label, onChange, m
return [
<AniMod {...{ render: MediaBusy, className: "fy-entity-input-busy", ...sharedProps }}/>,
<AniMod {...{ render: MocapInputFull, className: "fy-entity-input-full", ...sharedProps }}/>,
<AniMod {...{ render: MediaPickerEmpty, className: "fy-entity-input-empty", entityType, filterType, inputProps, onSelect, open, user, ...sharedProps }}/>
<AniMod {...{ render: MediaPickerEmpty, className: "fy-entity-input-empty", entityType, filterType, inputProps, onSelect, open, owner, user, ...sharedProps }}/>
][i];
})
@@ -11,6 +11,7 @@ export enum MediaFilters {
export enum WeightsFilters {
all,
hifigan_tt2,
rvc_v2,
sd_1,
"sd_1.5",
sdxl,
@@ -35,6 +36,6 @@ export const EntityFilterOptions = ( mode: EntityType, t = (v:string) => v) => {
.filter(val => isNaN(Number(val)))
.map((value) => {
if (typeof value === "string") return { value, label: t(value) }
return { label: "", value: "" };
return { label: "all", value: "all" };
}) : [];
};
@@ -2,7 +2,7 @@ import React, { useRef } from "react";
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia";
import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
import { ImagePreview, MocapPreview, VideoPreview } from '../CardPreviews';
import { AudioCard, OverlayCard, CardWrapper } from "components/entities";
import { AudioCard, OverlayCard, CardWrapper, WeightCard } from "components/entities";
import { EntityType } from "components/entities/EntityTypes";
interface MediaCardsProps {
@@ -33,6 +33,10 @@ const MediaCards = ({ props, type }: MediaCardsProps) => {
const WeightsCards = ({ props, type }: MediaCardsProps) => {
switch (type) {
case "rvc_v2":
return <CardWrapper {...{ ...props, card: WeightCard, padding: true }}/>;
case "tt2":
return <CardWrapper {...{ ...props, card: WeightCard, padding: true }}/>;
default:
return <div>Unsupported media type</div>;
}
@@ -0,0 +1,54 @@
import React from "react";
import moment from "moment";
import { MakeRatingsProps } from "hooks/useRatings";
import WeightCoverImage from "components/common/WeightCoverImage";
import CardBadge from "../CardBadge";
import CardFooter from "../CardFooter";
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
interface Props {
data: any,
makeRatingsProps?: MakeRatingsProps,
showCover?: boolean
showCreator?: boolean
}
export default function WeightCard({ data, makeRatingsProps, showCover = true, showCreator }: Props) {
const { cover_image, created_at, details, maybe_creator, title, token, weight_type } = data || {}
const timeCreated = moment( created_at || "").fromNow();
const path = cover_image.maybe_cover_image_public_bucket_path || details?.maybe_weight_data?.maybe_cover_image_public_bucket_path;
const bucketConfig = new BucketConfig();
const coverImage = bucketConfig.getCdnUrl(path, 110, 100);
return <>
<div className="d-flex">
{showCover && (
<WeightCoverImage
src={coverImage}
height={110}
width={110}
coverIndex={cover_image?.default_cover?.image_index}
/>
)}
<div className="flex-grow-1">
<CardBadge {...{ className: `fy-entity-type${ weight_type ? "-" + weight_type : "" }`, label: weight_type }}/>
<div className="d-flex align-items-center mt-3">
<div className="flex-grow-1">
<h6 className="fw-semibold text-white mb-1">
{ title || details.maybe_weight_data.title}
</h6>
<p className="fs-7 opacity-75">{ timeCreated }</p>
</div>
</div>
</div>
</div>
<CardFooter {...{
creator: maybe_creator,
entityToken: token,
entityType: "media_file",
makeRatingsProps
}}/>
</>;
};
@@ -0,0 +1 @@
export { default } from "./WeightCard";
@@ -3,5 +3,6 @@ import CardWrapper from "./CardWrapper";
import EntityInput from "./EntityInput";
import MediaList from "./MediaList";
import OverlayCard from "./OverlayCard";
import WeightCard from "./WeightCard";
export { AudioCard, CardWrapper, EntityInput, MediaList, OverlayCard };
export { AudioCard, CardWrapper, EntityInput, MediaList, OverlayCard, WeightCard };
@@ -20,12 +20,12 @@ interface Props {
handleClose: any,
mediaToken: string,
onSelect?: any,
owner?: string,
filterType?: MediaFilterProp | WeightFilterProp,
username: string,
}
export default function MediaBrowser({ entityType, filterType: inputFilter, mediaToken, handleClose = () => {}, onSelect, username }: Props) {
console.log("😎",entityType);
export default function MediaBrowser({ entityType, filterType: inputFilter, mediaToken, handleClose = () => {}, onSelect, owner, username }: Props) {
const ratings = useRatings();
const [showMasonryGrid, setShowMasonryGrid] = useState(true);
const [filterType, filterTypeSet] = useState(inputFilter || "all");
@@ -46,7 +46,7 @@ export default function MediaBrowser({ entityType, filterType: inputFilter, medi
setShowMasonryGrid(true);
},
requestList: true,
urlParam: "echelon",
urlParam: owner || username,
urlUpdate: false
});
@@ -74,7 +74,7 @@ export default function MediaBrowser({ entityType, filterType: inputFilter, medi
return <>
<header {...{ className: "fy-media-browser-header" }}>
<div {...{ className: "fy-media-browser-tools" }}>
<h3>{ ["","Media","Weights"][entityType] }</h3>
<h3>{ ["",`${ owner ? owner + "'s " : "" }Media`,"Weights"][entityType] }</h3>
<Icon {...{ className: "icon-close-button", icon: faXmark, onClick: () => handleClose() }}/>
</div>
<div {...{ className: "fy-media-browser-tools" }}>
@@ -13,10 +13,7 @@ interface ModalConfig {
export default function ModalProvider({ children }: Props) {
const [modalState,modalStateSet] = useState<ModalConfig | null>(null);
const open = (cfg: ModalConfig) => {
console.log("🪬",cfg);
modalStateSet(cfg);
};
const open = (cfg: ModalConfig) => modalStateSet(cfg);
const close = () => modalStateSet(null);
return <ModalContext.Provider {...{ value: { close, open, modalState } }}>
@@ -33,7 +33,6 @@ export default function useListContent({
urlParam = "",
urlUpdate = true
}: Props) {
console.log("💎",fetcher);
const { pathname, search: locSearch } = useLocation();
const history = useHistory();
const urlQueries = new URLSearchParams(locSearch);
@@ -1,12 +1,10 @@
.fy-engine-compositor {
// margin: 1rem;
padding: 1rem;
.engine-compositor-container {
padding: 1rem;
header {
// background: blue;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
@@ -14,16 +12,12 @@
width: 100%;
}
h2 { margin-bottom: 0; }
h2, .fy-temp-select, .fy-input { margin-bottom: 0; }
}
.compositor-content {
display: flex;
gap: 1rem;
// padding: 1rem;
> * {
width: 100%;
// background: red;
}
> * { width: 100%; }
}
}
@@ -1,11 +1,7 @@
import React, { useState } from "react";
import { EntityInput } from "components/entities";
import { Button } from "components/common";
// import { useInferenceJobs } from "hooks";
// import InferenceJobsList from "components/layout/InferenceJobsList";
// import { EnqueueEngineCompositing } from "@storyteller/components/src/api/engine_compositor/EnqueueEngineCompositing";
// import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
// import { v4 as uuidv4 } from "uuid";
import { EntityFilterOptions, EntityType, MediaFilterProp, WeightFilterProp } from "components/entities/EntityTypes";
import { Button, SegmentButtons, TempInput, TempSelect } from "components/common";
interface Props {
value?: any;
@@ -13,34 +9,34 @@ interface Props {
export default function DevMediaInput({ value }: Props) {
const [mediaToken,mediaTokenSet] = useState();
const [mediaType,mediaTypeSet] = useState<MediaFilterProp>("all");
const [weightType,weightTypeSet] = useState<WeightFilterProp>("all");
const [entityType,entityTypeSet] = useState(EntityType.media);
const [owner,ownerSet] = useState("");
const onChange = ({ target }: any) => mediaTokenSet(target.value);
// const inferenceJobs = useInferenceJobs(FrontendInferenceJobType.EngineComposition);
// const failures = (fail = "") => {
// switch (fail) {
// default:
// return "Uknown failure";
// }
// };
const options = [{ label: "Media", value: EntityType.media },{ label: "Weights", value: EntityType.weights }];
const changeFilter = ({ target }: { target: any }) => [mediaTypeSet,mediaTypeSet,weightTypeSet][entityType](target.value);
return <div {...{ className: "fy-engine-compositor"}}>
<div {...{ className: "panel engine-compositor-container" }}>
<header>
<h2>{ [526,187].map((num = 0) => String.fromCodePoint(128000 + num)) }</h2>
<SegmentButtons {...{ onChange: ({ target }: { target: any }) => entityTypeSet(target.value), options, value: entityType }}/>
<TempInput {...{ value: owner, onChange: ({ target }: { target: any }) => ownerSet(target.value), placeholder: "User" }}/>
<TempSelect {...{ options: EntityFilterOptions(entityType), value: ["",mediaType,weightType][entityType], onChange: changeFilter }}/>
<Button {...{ label: "Enqueue", variant: "primary" }}/>
</header>
<EntityInput {...{ aspectRatio: "landscape", label: "Choose Media File", onChange, weightType: "sd_1.5" }}/>
<EntityInput {...{
aspectRatio: "landscape",
label: `Choose ${ ["","media file","weight"][entityType] }`,
onChange,
owner,
...([{},{ mediaType },{ weightType }][entityType])
}}/>
<div>
{ mediaToken }
</div>
</div>
{
// <InferenceJobsList
// {...{
// failures,
// jobType: FrontendInferenceJobType.EngineComposition,
// }}
// />
}
</div>;
};