mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
got model images displaying, still need to clean up types and unused code
This commit is contained in:
parent
86aef9f31d
commit
8a68355926
@ -374,11 +374,6 @@ AnyModelConfig = Annotated[
|
|||||||
|
|
||||||
AnyModelConfigValidator = TypeAdapter(AnyModelConfig)
|
AnyModelConfigValidator = TypeAdapter(AnyModelConfig)
|
||||||
|
|
||||||
|
|
||||||
class ModelImage(str, Enum):
|
|
||||||
path: str
|
|
||||||
|
|
||||||
|
|
||||||
class ModelConfigFactory(object):
|
class ModelConfigFactory(object):
|
||||||
"""Class for parsing config dicts into StableDiffusion Config obects."""
|
"""Class for parsing config dicts into StableDiffusion Config obects."""
|
||||||
|
|
||||||
|
6
invokeai/frontend/package-lock.json
generated
Normal file
6
invokeai/frontend/package-lock.json
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
12557
invokeai/frontend/web/package-lock.json
generated
Normal file
12557
invokeai/frontend/web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -829,6 +829,7 @@
|
|||||||
"repo_id": "Repo ID",
|
"repo_id": "Repo ID",
|
||||||
"repoIDValidationMsg": "Online repository of your model",
|
"repoIDValidationMsg": "Online repository of your model",
|
||||||
"repoVariant": "Repo Variant",
|
"repoVariant": "Repo Variant",
|
||||||
|
"resetImage": "Reset This Image",
|
||||||
"safetensorModels": "SafeTensors",
|
"safetensorModels": "SafeTensors",
|
||||||
"sameFolder": "Same folder",
|
"sameFolder": "Same folder",
|
||||||
"scan": "Scan",
|
"scan": "Scan",
|
||||||
@ -853,6 +854,7 @@
|
|||||||
"triggerPhrases": "Trigger Phrases",
|
"triggerPhrases": "Trigger Phrases",
|
||||||
"typePhraseHere": "Type phrase here",
|
"typePhraseHere": "Type phrase here",
|
||||||
"upcastAttention": "Upcast Attention",
|
"upcastAttention": "Upcast Attention",
|
||||||
|
"uploadImage":"Upload Image",
|
||||||
"updateModel": "Update Model",
|
"updateModel": "Update Model",
|
||||||
"useCustomConfig": "Use Custom Config",
|
"useCustomConfig": "Use Custom Config",
|
||||||
"useDefaultSettings": "Use Default Settings",
|
"useDefaultSettings": "Use Default Settings",
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
import { Box, Image } from '@invoke-ai/ui-library';
|
||||||
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
import { buildModelsUrl } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
model_key: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ModelImage = ({ model_key }: Props) => {
|
||||||
|
const [image, setImage] = useState<string | undefined>(buildModelsUrl(`i/${model_key}/image`));
|
||||||
|
|
||||||
|
if (!image) return <Box height="50px" width="50px"></Box>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Image
|
||||||
|
onError={() => setImage(undefined)}
|
||||||
|
src={image}
|
||||||
|
objectFit="cover"
|
||||||
|
objectPosition="50% 50%"
|
||||||
|
height="50px"
|
||||||
|
width="50px"
|
||||||
|
borderRadius="base"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default typedMemo(ModelImage);
|
@ -21,6 +21,7 @@ import { IoWarning } from 'react-icons/io5';
|
|||||||
import { PiTrashSimpleBold } from 'react-icons/pi';
|
import { PiTrashSimpleBold } from 'react-icons/pi';
|
||||||
import { useDeleteModelsMutation } from 'services/api/endpoints/models';
|
import { useDeleteModelsMutation } from 'services/api/endpoints/models';
|
||||||
import type { AnyModelConfig } from 'services/api/types';
|
import type { AnyModelConfig } from 'services/api/types';
|
||||||
|
import ModelImage from './ModelImage';
|
||||||
|
|
||||||
type ModelListItemProps = {
|
type ModelListItemProps = {
|
||||||
model: AnyModelConfig;
|
model: AnyModelConfig;
|
||||||
@ -73,6 +74,7 @@ const ModelListItem = (props: ModelListItemProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex gap={2} alignItems="center" w="full">
|
<Flex gap={2} alignItems="center" w="full">
|
||||||
|
<ModelImage model_key={model.key} />
|
||||||
<Flex
|
<Flex
|
||||||
as={Button}
|
as={Button}
|
||||||
isChecked={isSelected}
|
isChecked={isSelected}
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
import { Box, IconButton, Image } from '@invoke-ai/ui-library';
|
import { Box, IconButton, Image } from '@invoke-ai/ui-library';
|
||||||
import { typedMemo } from 'common/util/typedMemo';
|
import { typedMemo } from 'common/util/typedMemo';
|
||||||
import { useCallback, useEffect, useMemo } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import type { UseControllerProps } from 'react-hook-form';
|
import type { Control } from 'react-hook-form';
|
||||||
import { useController, useWatch } from 'react-hook-form';
|
import { useController, useWatch } from 'react-hook-form';
|
||||||
import type { AnyModelConfig } from 'services/api/types';
|
|
||||||
|
|
||||||
import { Button } from '@invoke-ai/ui-library';
|
import { Button } from '@invoke-ai/ui-library';
|
||||||
import { useDropzone } from 'react-dropzone';
|
import { useDropzone } from 'react-dropzone';
|
||||||
import { PiArrowCounterClockwiseBold, PiUploadSimpleBold } from 'react-icons/pi';
|
import { PiArrowCounterClockwiseBold, PiUploadSimpleBold } from 'react-icons/pi';
|
||||||
import { useGetModelImageQuery } from 'services/api/endpoints/models';
|
import { UpdateModelArg, buildModelsUrl } from 'services/api/endpoints/models';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ModelImageUpload = (props: UseControllerProps<AnyModelConfig>) => {
|
type Props = {
|
||||||
const { field } = useController(props);
|
control: Control<UpdateModelArg['body']>;
|
||||||
|
};
|
||||||
|
|
||||||
const key = useWatch({ control: props.control, name: 'key' });
|
const ModelImageUpload = ({ control }: Props) => {
|
||||||
|
const key = useWatch({ control, name: 'key' });
|
||||||
const { data } = useGetModelImageQuery(key);
|
const [image, setImage] = useState<string | undefined>(buildModelsUrl(`i/${key}/image`));
|
||||||
|
const { field } = useController({ control, name: 'image' });
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const onDropAccepted = useCallback(
|
const onDropAccepted = useCallback(
|
||||||
(files: File[]) => {
|
(files: File[]) => {
|
||||||
@ -26,12 +29,14 @@ const ModelImageUpload = (props: UseControllerProps<AnyModelConfig>) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
field.onChange(file);
|
field.onChange(file);
|
||||||
|
setImage(URL.createObjectURL(file));
|
||||||
},
|
},
|
||||||
[field]
|
[field]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleResetControlImage = useCallback(() => {
|
const handleResetImage = useCallback(() => {
|
||||||
field.onChange(undefined);
|
field.onChange(undefined);
|
||||||
|
setImage(undefined);
|
||||||
}, [field]);
|
}, [field]);
|
||||||
|
|
||||||
const { getInputProps, getRootProps } = useDropzone({
|
const { getInputProps, getRootProps } = useDropzone({
|
||||||
@ -41,29 +46,28 @@ const ModelImageUpload = (props: UseControllerProps<AnyModelConfig>) => {
|
|||||||
multiple: false,
|
multiple: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const image = useMemo(() => {
|
|
||||||
console.log(field.value, 'asdf' );
|
|
||||||
if (field.value) {
|
|
||||||
return URL.createObjectURL(field.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}, [field.value, data]);
|
|
||||||
|
|
||||||
if (image) {
|
if (image) {
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box
|
||||||
|
position="relative"
|
||||||
|
_hover={{ filter: 'brightness(50%)' }}
|
||||||
|
transition="filter ease 0.2s"
|
||||||
|
>
|
||||||
<Image
|
<Image
|
||||||
|
onError={() => setImage(undefined)}
|
||||||
src={image}
|
src={image}
|
||||||
objectFit="contain"
|
objectFit="contain"
|
||||||
maxW="full"
|
maxW="full"
|
||||||
maxH="200px"
|
maxH="100px"
|
||||||
borderRadius="base"
|
borderRadius="base"
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={handleResetControlImage}
|
position="absolute"
|
||||||
aria-label="reset this image"
|
top="1"
|
||||||
tooltip="reset this image"
|
right="1"
|
||||||
|
onClick={handleResetImage}
|
||||||
|
aria-label={t('modelManager.resetImage')}
|
||||||
|
tooltip={t('modelManager.resetImage')}
|
||||||
icon={<PiArrowCounterClockwiseBold size={16} />}
|
icon={<PiArrowCounterClockwiseBold size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="link"
|
variant="link"
|
||||||
@ -75,7 +79,7 @@ const ModelImageUpload = (props: UseControllerProps<AnyModelConfig>) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button leftIcon={<PiUploadSimpleBold />} {...getRootProps()} pointerEvents="auto">
|
<Button leftIcon={<PiUploadSimpleBold />} {...getRootProps()} pointerEvents="auto">
|
||||||
Upload Image
|
{t('modelManager.uploadImage')}
|
||||||
</Button>
|
</Button>
|
||||||
<input {...getInputProps()} />
|
<input {...getInputProps()} />
|
||||||
</>
|
</>
|
||||||
|
@ -168,7 +168,7 @@ export const ModelEdit = () => {
|
|||||||
|
|
||||||
<Flex flexDir="column" gap={3} mt="4">
|
<Flex flexDir="column" gap={3} mt="4">
|
||||||
<Flex gap="4" alignItems="center">
|
<Flex gap="4" alignItems="center">
|
||||||
<ModelImageUpload control={control} name="image" />
|
<ModelImageUpload control={control} />
|
||||||
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
|
<FormControl flexDir="column" alignItems="flex-start" gap={1}>
|
||||||
<FormLabel>{t('modelManager.description')}</FormLabel>
|
<FormLabel>{t('modelManager.description')}</FormLabel>
|
||||||
<Textarea fontSize="md" resize="none" {...register('description')} />
|
<Textarea fontSize="md" resize="none" {...register('description')} />
|
||||||
|
@ -25,14 +25,12 @@ export type UpdateModelArg = {
|
|||||||
|
|
||||||
export type UpdateModelImageArg = {
|
export type UpdateModelImageArg = {
|
||||||
key: paths['/api/v2/models/i/{key}/image']['patch']['parameters']['path']['key'];
|
key: paths['/api/v2/models/i/{key}/image']['patch']['parameters']['path']['key'];
|
||||||
image: paths['/api/v2/models/i/{key}/image']['patch']['formData']['content']['multipart/form-data'];
|
image: paths['/api/v2/models/i/{key}/image']['patch']['requestBody']['content']['multipart/form-data'];
|
||||||
};
|
};
|
||||||
|
|
||||||
type UpdateModelResponse = paths['/api/v2/models/i/{key}']['patch']['responses']['200']['content']['application/json'];
|
type UpdateModelResponse = paths['/api/v2/models/i/{key}']['patch']['responses']['200']['content']['application/json'];
|
||||||
type UpdateModelImageResponse =
|
type UpdateModelImageResponse =
|
||||||
paths['/api/v2/models/i/{key}/image']['patch']['responses']['200']['content']['application/json'];
|
paths['/api/v2/models/i/{key}/image']['patch']['responses']['200']['content']['application/json'];
|
||||||
type GetModelImageResponse =
|
|
||||||
paths['/api/v2/models/i/{key}/image']['get']['responses']['200']['content']['application/json'];
|
|
||||||
|
|
||||||
type GetModelConfigResponse = paths['/api/v2/models/i/{key}']['get']['responses']['200']['content']['application/json'];
|
type GetModelConfigResponse = paths['/api/v2/models/i/{key}']['get']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
@ -139,7 +137,7 @@ const buildTransformResponse =
|
|||||||
* buildModelsUrl('some-path')
|
* buildModelsUrl('some-path')
|
||||||
* // '/api/v1/models/some-path'
|
* // '/api/v1/models/some-path'
|
||||||
*/
|
*/
|
||||||
const buildModelsUrl = (path: string = '') => buildV2Url(`models/${path}`);
|
export const buildModelsUrl = (path: string = '') => buildV2Url(`models/${path}`);
|
||||||
|
|
||||||
export const modelsApi = api.injectEndpoints({
|
export const modelsApi = api.injectEndpoints({
|
||||||
endpoints: (build) => ({
|
endpoints: (build) => ({
|
||||||
@ -153,13 +151,10 @@ export const modelsApi = api.injectEndpoints({
|
|||||||
},
|
},
|
||||||
invalidatesTags: ['Model'],
|
invalidatesTags: ['Model'],
|
||||||
}),
|
}),
|
||||||
getModelImage: build.query<GetModelImageResponse, string>({
|
|
||||||
query: (key) => buildModelsUrl(`i/${key}/image`),
|
|
||||||
}),
|
|
||||||
updateModelImage: build.mutation<UpdateModelImageResponse, UpdateModelImageArg>({
|
updateModelImage: build.mutation<UpdateModelImageResponse, UpdateModelImageArg>({
|
||||||
query: ({ key, image }) => {
|
query: ({ key, image }) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('image', image);
|
formData.append('image', image.image);
|
||||||
return {
|
return {
|
||||||
url: buildModelsUrl(`i/${key}/image`),
|
url: buildModelsUrl(`i/${key}/image`),
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
@ -354,8 +349,7 @@ export const {
|
|||||||
useGetTextualInversionModelsQuery,
|
useGetTextualInversionModelsQuery,
|
||||||
useGetVaeModelsQuery,
|
useGetVaeModelsQuery,
|
||||||
useDeleteModelsMutation,
|
useDeleteModelsMutation,
|
||||||
useUpdateModelsMutation,
|
useUpdateModelMutation,
|
||||||
useGetModelImageQuery,
|
|
||||||
useUpdateModelImageMutation,
|
useUpdateModelImageMutation,
|
||||||
useInstallModelMutation,
|
useInstallModelMutation,
|
||||||
useConvertModelMutation,
|
useConvertModelMutation,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user