mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): use dropzone for style preset upload
Easier to accept multiple file types and supper drag and drop in the future.
This commit is contained in:
parent
76b0380b5f
commit
15415c6d85
@ -1,8 +1,8 @@
|
|||||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||||
import { IconButton, spinAnimation, Text } from '@invoke-ai/ui-library';
|
import { IconButton, spinAnimation, Text } from '@invoke-ai/ui-library';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import type { ChangeEvent } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useCallback, useRef } from 'react';
|
import { useDropzone } from 'react-dropzone';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiSpinner, PiUploadBold } from 'react-icons/pi';
|
import { PiSpinner, PiUploadBold } from 'react-icons/pi';
|
||||||
import { useImportStylePresetsMutation } from 'services/api/endpoints/stylePresets';
|
import { useImportStylePresetsMutation } from 'services/api/endpoints/stylePresets';
|
||||||
@ -13,23 +13,14 @@ const loadingStyles: SystemStyleObject = {
|
|||||||
|
|
||||||
export const StylePresetImport = () => {
|
export const StylePresetImport = () => {
|
||||||
const [importStylePresets, { isLoading }] = useImportStylePresetsMutation();
|
const [importStylePresets, { isLoading }] = useImportStylePresetsMutation();
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleClickUpload = useCallback(() => {
|
const onDropAccepted = useCallback(
|
||||||
if (fileInputRef.current) {
|
async (files: File[]) => {
|
||||||
fileInputRef.current.click();
|
const file = files[0];
|
||||||
}
|
|
||||||
}, [fileInputRef]);
|
|
||||||
|
|
||||||
const handleFileChange = useCallback(
|
|
||||||
async (event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
if (event.target.files) {
|
|
||||||
const file = event.target.files[0];
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await importStylePresets(file).unwrap();
|
await importStylePresets(file).unwrap();
|
||||||
toast({
|
toast({
|
||||||
@ -42,15 +33,19 @@ export const StylePresetImport = () => {
|
|||||||
title: t('toast.importFailed'),
|
title: t('toast.importFailed'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[importStylePresets, t]
|
[importStylePresets, t]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
const { getInputProps, getRootProps } = useDropzone({
|
||||||
<div>
|
accept: { 'text/csv': ['.csv'], 'application/json': ['.json'] },
|
||||||
<input type="file" accept=".csv" onChange={handleFileChange} hidden ref={fileInputRef} />
|
onDropAccepted,
|
||||||
|
noDrag: true,
|
||||||
|
multiple: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={!isLoading ? <PiUploadBold /> : <PiSpinner />}
|
icon={!isLoading ? <PiUploadBold /> : <PiSpinner />}
|
||||||
tooltip={
|
tooltip={
|
||||||
@ -60,14 +55,15 @@ export const StylePresetImport = () => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
aria-label={t('stylePresets.importTemplates')}
|
aria-label={t('stylePresets.importTemplates')}
|
||||||
onClick={handleClickUpload}
|
|
||||||
size="md"
|
size="md"
|
||||||
variant="link"
|
variant="link"
|
||||||
w={8}
|
w={8}
|
||||||
h={8}
|
h={8}
|
||||||
sx={isLoading ? loadingStyles : undefined}
|
sx={isLoading ? loadingStyles : undefined}
|
||||||
isDisabled={isLoading}
|
isDisabled={isLoading}
|
||||||
|
{...getRootProps()}
|
||||||
/>
|
/>
|
||||||
</div>
|
<input {...getInputProps()} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user